[ruby-dev:50257] [Ruby trunk Bug#13917] Comparable#clamp is slower than using Array#min, max.
From:
kei.shiratsuchi@...
Date:
2017-09-21 09:39:54 UTC
List:
ruby-dev #50257
Issue #13917 has been updated by kei-s (Kei Shiratsuchi).
Thank you, Hanmac. I understand why `Array#min/max` is so fast.
I guess `clamp` would be implemented in `numeric.c` and so on to be as fast as `Array#min/max`.
----------------------------------------
Bug #13917: Comparable#clamp is slower than using Array#min,max.
https://bugs.ruby-lang.org/issues/13917#change-66816
* Author: kei-s (Kei Shiratsuchi)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v:
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
Comparable#clamp is slower than using Array#min,max.
(I noticed it by @onk's tweet. https://twitter.com/onk/status/907856892604461056)
### Performance
```
user system total real
minmax: 0.740000 0.000000 0.740000 ( 0.732744)
clamp: 2.060000 0.010000 2.070000 ( 2.072794)
```
### Test Code
```
require 'benchmark'
Benchmark.bmbm do |x|
v = Random.rand(-10..110)
x.report "minmax:" do
10000000.times { [99, [0, v].max].min }
end
x.report "clamp: " do
10000000.times { v.clamp(0, 99) }
end
end
```
# Patch
I made patch for it. But I'm not sure this is good way.
https://gist.github.com/kei-s/b303aca105df5c26be9c98f833db80f7#file-compar-diff
## After
```
user system total real
minmax: 0.820000 0.000000 0.820000 ( 0.822517)
clamp: 1.090000 0.000000 1.090000 ( 1.087491)
```
Other benchmark for this patch is here.
https://gist.github.com/kei-s/0c34cbe4e21a499601e8247077629082
## Questions
1. Should `clamp` version be faster than `Array#min/max` version?
`Array#min/max` version would have overhead of array creation.
2. Is `OPTIMIZED_CMP` in `cmpint` best way?
Some method doesn't pass `cmpint` (e.g. `Integer#>`). But `OPTMIZED_CMP` checks Integer.
--
https://bugs.ruby-lang.org/