Issue #14476 has been updated by Eregon (Benoit Daloze).
Why would it be more efficient in C?
A sufficiently smart JIT could turn
ary.all? {|e| e.foo == ary[0].foo }
into (assuming foo has no side effects):
e0 = ary[0].foo
ary.all? {|e| e.foo == e0 }
and then the only performance difference is the extra comparison of ary[0].foo with itself,
which could be avoided by:
e0 = ary[0].foo
(1...ary.size).all? {|i| ary[i].foo == e0 }
----------------------------------------
Feature #14476: Adding same_all? for checking whether all items in an Array are same
https://bugs.ruby-lang.org/issues/14476#change-70340
* Author: mrkn (Kenta Murata)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 2.6
----------------------------------------
In this issue, I propose to introduce `same_all?` instance method of `Array` class.
This new method checks whether the all items in the receiver are same.
Today, I needed to write the code to judge whether all items in an Array are same.
I wanted to make the following expression, that I've written at first, more efficiently.
```ruby
ary.all? {|e| e.foo == ary[0].foo }
```
I thought the following another simpler case, too.
```ruby
ary.all? {|e| e == ary[0] }
```
As I discussed with some CRuby committers and my colleagues at Speee, Inc., I found that both cases have the following efficient expressions:
```ruby
# for the 1st case
ary.empty? || ary[0].foo.yield_self {|e0| ary[1..-1].all? {|e| e.foo == e0 } }
# for the 2nd case
ary.empty? || ary[0..-2] == ary[1..-1]
```
Both expressions aren't easy to understand the original purpose that is checking whether all the items are same.
I want to give this feature a clear name to make the code readable.
And I think it should be provided as a core feature because it can be more efficient by implementing in C language.
The benchmark script is: https://gist.github.com/mrkn/26a0fcfc431a45fe809fbbef95aceaf5
I used it to find the efficient expressions.
The example result of this benchmark on my MacBook Pro is here.
```
$ ruby -v bench.rb
ruby 2.6.0dev (2018-02-14 trunk 62402) [x86_64-darwin16]
----------------------------------------
Benchmark case: shuffle
user system total real
all?-method-1 0.001525 0.000088 0.001613 ( 0.001632)
all?-method-2 0.000489 0.000031 0.000520 ( 0.000565)
all?-method-3 0.000444 0.000039 0.000483 ( 0.000482)
all?-item 0.000325 0.000078 0.000403 ( 0.000402)
opt-method 0.655959 0.033814 0.689773 ( 0.708515)
opt-item 0.000316 0.000001 0.000317 ( 0.000317)
----------------------------------------
Benchmark case: tail0
user system total real
all?-method-1 9.412810 0.231126 9.643936 ( 9.681118)
all?-method-2 5.375075 0.137908 5.512983 ( 5.754550)
all?-method-3 5.226132 0.167640 5.393772 ( 5.507031)
all?-item 0.873700 0.007545 0.881245 ( 0.917210)
opt-method 5.319648 0.172547 5.492195 ( 5.633140)
opt-item 0.174349 0.001974 0.176323 ( 0.183002)
----------------------------------------
Benchmark case: head0
user system total real
all?-method-1 0.002421 0.000068 0.002489 ( 0.002489)
all?-method-2 0.002169 0.000213 0.002382 ( 0.002382)
all?-method-3 0.001624 0.000026 0.001650 ( 0.001651)
all?-item 0.000623 0.000001 0.000624 ( 0.000624)
opt-method 4.779120 0.146312 4.925432 ( 4.951167)
opt-item 0.000629 0.000001 0.000630 ( 0.000629)
----------------------------------------
Benchmark case: all1
user system total real
all?-method-1 9.379650 0.255865 9.635515 ( 9.683078)
all?-method-2 4.950280 0.150659 5.100939 ( 5.140174)
all?-method-3 4.857898 0.129125 4.987023 ( 5.003142)
all?-item 0.694113 0.001295 0.695408 ( 0.702370)
opt-method 5.032373 0.121708 5.154081 ( 5.189599)
opt-item 0.170540 0.002069 0.172609 ( 0.180343)
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>