[ruby-core:93205] [Ruby trunk Bug#15929] Array#minmax is much slower than calling both #min and #max
From:
merch-redmine@...
Date:
2019-06-17 18:48:53 UTC
List:
ruby-core #93205
Issue #15929 has been updated by jeremyevans0 (Jeremy Evans).
File array-minmax.patch added
janosch-x (Janosch Mler) wrote:
> possible solutions:
> - a) change `Enumerable#minmax` and let it `rb_funcall` `min` and `max` as suggested [here](https://bugs.ruby-lang.org/issues/15807#note-7) (will also fix 15807)
We cannot use this approach. `Enumerable#each` can have side effects, and you cannot iterate twice for `minmax` in the general case. Consider:
```ruby
File.open('...', &:minmax)
```
> - b) implement minmax in array.c to call `rb_ary_min` and `rb_ary_max`
I think this is the correct approach in Array and any other class that overrides `min`/`max`. Attached is a patch that implements it.
----------------------------------------
Bug #15929: Array#minmax is much slower than calling both #min and #max
https://bugs.ruby-lang.org/issues/15929#change-78653
* Author: janosch-x (Janosch Mler)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: 2.7.0dev
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
this is similar to [issue 15807 about Ranges](https://bugs.ruby-lang.org/issues/15807) and maybe also to [13917](https://bugs.ruby-lang.org/issues/13917)
current situation:
- calling `Array#minmax` incurs a performance penalty of almost 50% compared to calling both `#min` and `#max`
```ruby
require 'benchmark/ips'
arr = (1..1000).map { rand }
Benchmark.ips do |x|
x.report('min, max') { [arr.min, arr.max] }
x.report('minmax') { arr.minmax }
end
```
```
min, max 53.832k (ア 1.8%) i/s - 270.861k in 5.033263s
minmax 30.093k (ア 1.2%) i/s - 151.980k in 5.051078s
```
background:
- `#minmax` is included via `Enumerable`
- `Enumerable#minmax` does not call array's optimized `#min` and `#max` implementations
possible solutions:
- a) change `Enumerable#minmax` and let it `rb_funcall` `min` and `max` as suggested [here](https://bugs.ruby-lang.org/issues/15807#note-7) (will also fix 15807)
- b) implement minmax in array.c to call `rb_ary_min` and `rb_ary_max`
---Files--------------------------------
array-minmax.patch (2.65 KB)
--
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>