Conversation
| * of the collection; returns the last element for which the block returns a | ||
| * truthy value: | ||
| * | ||
| * (0..9).find {|element| element > 2} # => 3 |
There was a problem hiding this comment.
The examples need to be updated
| * (0..9).find {|element| element > 2} # => 3 | |
| * (0..9).rfind {|element| element < 5} # => 4 |
| * (0..9).find(proc {false}) {|element| element > 12} # => false | ||
| * {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1] | ||
| * {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => [] |
There was a problem hiding this comment.
It would be better to provide examples more specific to rfind, but here's a temporary fix:
| * (0..9).find(proc {false}) {|element| element > 12} # => false | |
| * {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1] | |
| * {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => [] | |
| * (0..9).rfind(proc {false}) {|element| element > 12} # => false | |
| * {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2] | |
| * {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => [] |
|
|
||
| def test_rfind | ||
| ary = [1, 2, 3, 1, 2] | ||
| assert_equal(2, ary.rfind {|x| x % 2 == 0 }) |
There was a problem hiding this comment.
I see this test was ported from test_enum.rb, but shouldn't we add tests to verify behavior specific to rfind? This test doesn't distinguish which 2 is returned and doesn't express the difference from find.
| * | ||
| * Returns the first element for which the block returns a truthy value. | ||
| * | ||
| * With a block given, calls the block with successive elements of the collection; |
There was a problem hiding this comment.
nitpicking: in Enumerable, it seems the word "collection" refers to the objects yielded by each method. However, I feel this word slightly off in Array. In fact, the word "collection" hardly appears at all in array.c.
As defined below, "elements" seems like a better choice.
Lines 8264 to 8265 in bec6961
Well, since it says "collection of objects", you could say it's not incorrect, though. Also, "successive elements of the elements" may be awkward. I cannot think of a better phrase. Just for your reference.
|
I don't think you can cache |
Implement Array#rfind, which is the same as find except from the other side of the Array. Also implemented Array#find (as opposed to the generic one on Enumerable because it is significantly faster and to keep the implementations together. [Feature #21678]
170da6c to
409c331
Compare
|
Thanks @mame and @luke-gruber — I believe I've addressed both your comments. |
|
@kddnewton Nice! Could you also add an entry for this in NEWS.md? |
|
I pushed bbc10ed to make sure we don't forget, feel free to improve it/tweak it. |
|
Thanks that looks good. |
Inspired by https://bugs.ruby-lang.org/issues/20182 and ruby#9533. This PR provides a performance boost to Array#find when run using JIT compilation. This is achieved by implementing Array#find in Ruby, which the JIT compiler can optimise. [PR#15189](ruby#15189) added a C implementation for Array#find instead of relying on Enumerable#find. This PR extends this by adding a Ruby implementation. I used the so_fasta benchmark to measure performance. No change in interpreted performance before/after: $ benchmark-driver -e "~/.rubies/ruby-master/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-master/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby so_fasta 0.393 0.393 i/s - 1.000 times in 2.543209s 2.545514s Comparison: so_fasta ~/.rubies/ruby-master/bin/ruby: 0.4 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.00x slower With YJIT enabled the speed is almost twice as fast: $ benchmark-driver -e "~/.rubies/ruby-array-find-native/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby --yjit" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-array-find-native/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby --yjit so_fasta 0.393 0.770 i/s - 1.000 times in 2.547550s 1.298371s Comparison: so_fasta ~/.rubies/ruby-array-find-native/bin/ruby --yjit: 0.8 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.96x slower
Inspired by https://bugs.ruby-lang.org/issues/20182 and ruby#9533. This PR provides a performance boost to Array#find when run using JIT compilation. This is achieved by implementing Array#find in Ruby, which the JIT compiler can optimise. [PR#15189](ruby#15189) added a C implementation for Array#find instead of relying on Enumerable#find. This PR extends this by adding a Ruby implementation. I used the so_fasta benchmark to measure performance. No change in interpreted performance before/after: $ benchmark-driver -e "~/.rubies/ruby-master/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-master/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby so_fasta 0.393 0.393 i/s - 1.000 times in 2.543209s 2.545514s Comparison: so_fasta ~/.rubies/ruby-master/bin/ruby: 0.4 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.00x slower With YJIT enabled Array#find is almost twice as fast: $ benchmark-driver -e "~/.rubies/ruby-array-find-native/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby --yjit" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-array-find-native/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby --yjit so_fasta 0.393 0.770 i/s - 1.000 times in 2.547550s 1.298371s Comparison: so_fasta ~/.rubies/ruby-array-find-native/bin/ruby --yjit: 0.8 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.96x slower
Inspired by https://bugs.ruby-lang.org/issues/20182 and ruby#9533. This PR provides a performance boost to Array#find when run using JIT compilation. This is achieved by implementing Array#find in Ruby, which the JIT compiler can optimise. [PR#15189](ruby#15189) added a C implementation for Array#find instead of relying on Enumerable#find. This PR extends this by adding a Ruby implementation. I used the so_fasta benchmark to measure performance. No change in interpreted performance before/after: $ benchmark-driver -e "~/.rubies/ruby-master/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-master/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby so_fasta 0.393 0.393 i/s - 1.000 times in 2.543209s 2.545514s Comparison: so_fasta ~/.rubies/ruby-master/bin/ruby: 0.4 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.00x slower With YJIT enabled Array#find is almost twice as fast: $ benchmark-driver -e "~/.rubies/ruby-array-find-native/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby --yjit" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-array-find-native/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby --yjit so_fasta 0.393 0.770 i/s - 1.000 times in 2.547550s 1.298371s Comparison: so_fasta ~/.rubies/ruby-array-find-native/bin/ruby --yjit: 0.8 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.96x slower
Inspired by https://bugs.ruby-lang.org/issues/20182 and #9533. This PR provides a performance boost to Array#find when run using JIT compilation. This is achieved by implementing Array#find in Ruby, which the JIT compiler can optimise. [PR#15189](#15189) added a C implementation for Array#find instead of relying on Enumerable#find. This PR extends this by adding a Ruby implementation. I used the so_fasta benchmark to measure performance. No change in interpreted performance before/after: $ benchmark-driver -e "~/.rubies/ruby-master/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-master/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby so_fasta 0.393 0.393 i/s - 1.000 times in 2.543209s 2.545514s Comparison: so_fasta ~/.rubies/ruby-master/bin/ruby: 0.4 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.00x slower With YJIT enabled Array#find is almost twice as fast: $ benchmark-driver -e "~/.rubies/ruby-array-find-native/bin/ruby; ~/.rubies/ruby-array-find-native/bin/ruby --yjit" ../benchmark/so_fasta.rb Calculating ------------------------------------- ~/.rubies/ruby-array-find-native/bin/ruby ~/.rubies/ruby-array-find-native/bin/ruby --yjit so_fasta 0.393 0.770 i/s - 1.000 times in 2.547550s 1.298371s Comparison: so_fasta ~/.rubies/ruby-array-find-native/bin/ruby --yjit: 0.8 i/s ~/.rubies/ruby-array-find-native/bin/ruby: 0.4 i/s - 1.96x slower
Implement Array#rfind, which is the same as find except from the other side of the Array. Also implemented Array#find (as opposed to the generic one on Enumerable because it is significantly faster and to keep the implementations together.
[Feature #21678]