Project

General

Profile

Actions

Feature #18515

open

Add Range#reverse_each implementation for performance

Added by kyanagi (Kouhei Yanagita) 10 months ago. Updated 10 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:107285]

Description

PR is https://github.com/ruby/ruby/pull/5489

Current Range#reverse_each uses Enumerable#reverse_each which is implemented with #to_a.
So we are virtually not able to use reverse_each for a very large or beginless range, even if few elements are iterated on actually.

(1..2**100).reverse_each { |x| p x; break if x.odd? }
(..5).reverse_each { |x| p x; break if x == 0 }
(1..2**32).reverse_each.lazy.select { |x| Prime.prime?(x) }.take(3).to_a

This patch, implements Range#reverse_each for Integer elements, enables these examples.

I think #reverse_each for an endless range should raise an exception.
This is a different issue, so I'll create another ticket later.
-> posted: https://bugs.ruby-lang.org/issues/18551

Actions #1

Updated by kyanagi (Kouhei Yanagita) 10 months ago

  • Description updated (diff)

Updated by kyanagi (Kouhei Yanagita) 10 months ago

In general, I think it would be better to improve #reverse_each by using #pred (predecessor; the inverse of #succ) if the element has.

However, since integer ranges are used so often, I think it is acceptable to add specialized implementation to Range.

Updated by Dan0042 (Daniel DeLorme) 10 months ago

kyanagi (Kouhei Yanagita) wrote in #note-2:

In general, I think it would be better to improve #reverse_each by using #pred (predecessor; the inverse of #succ) if the element has.

However, since integer ranges are used so often, I think it is acceptable to add specialized implementation to Range.

I agree with both of those statements, but Integer is the only class that has #pred, so in practice "using pred" and "specialized implementation for Integer" are the same thing. Maybe Date could benefit from having #pred (and by extension an optimized #reverse_each implementation) but I can't think of any other core classes to which this would apply.

Updated by kyanagi (Kouhei Yanagita) 10 months ago

Dan0042 (Daniel DeLorme) wrote in #note-3:

I agree with both of those statements, but Integer is the only class that has #pred, so in practice "using pred" and "specialized implementation for Integer" are the same thing.

Yes, that is exactly what you said.

If I propose #pred-based Range#reverse_each, I will propose Date#pred too.

To find out my PR implementation (iterating integers directly) is worthwhile even if a #pred-based implementation is introduced,
we will need to measure the performance. I'll try it later.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0