diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2024-07-02 18:29:23 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2024-07-03 10:01:41 -0700 |
commit | f4b313f7338f5fbe37f73aae29f70aeb474f7f5b (patch) | |
tree | 93b8697803d2ecd9553119bd44b0dab43cb09015 /numeric.rb | |
parent | cbc40aca3ae5f139235724d4c6f9b63d0dd4e962 (diff) |
move Integer#downto to Ruby
Speeds up ChunkyPNG.
The interpreter is about 70% faster:
```
before: ruby 3.4.0dev (2024-07-03T15:16:17Z master 786cf9db48) [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T15:32:25Z ruby-downto 0b8b744ce2) [arm64-darwin23]
---------- ----------- ---------- ---------- ---------- ------------- ------------
bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after
chunky-png 892.2 0.1 526.3 1.0 1.65 1.70
---------- ----------- ---------- ---------- ---------- ------------- ------------
Legend:
- after 1st itr: ratio of before/after time for the first benchmarking iteration.
- before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup.
```
YJIT is 2.5x faster:
```
before: ruby 3.4.0dev (2024-07-03T15:16:17Z master 786cf9db48) +YJIT [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T15:32:25Z ruby-downto 0b8b744ce2) +YJIT [arm64-darwin23]
---------- ----------- ---------- ---------- ---------- ------------- ------------
bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after
chunky-png 709.4 0.1 278.8 0.3 2.35 2.54
---------- ----------- ---------- ---------- ---------- ------------- ------------
Legend:
- after 1st itr: ratio of before/after time for the first benchmarking iteration.
- before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup.
```
Diffstat (limited to 'numeric.rb')
-rw-r--r-- | numeric.rb | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/numeric.rb b/numeric.rb index 4dc406fd23..ebe06a7666 100644 --- a/numeric.rb +++ b/numeric.rb @@ -241,6 +241,35 @@ class Integer self end + # call-seq: + # downto(limit) {|i| ... } -> self + # downto(limit) -> enumerator + # + # Calls the given block with each integer value from +self+ down to +limit+; + # returns +self+: + # + # a = [] + # 10.downto(5) {|i| a << i } # => 10 + # a # => [10, 9, 8, 7, 6, 5] + # a = [] + # 0.downto(-5) {|i| a << i } # => 0 + # a # => [0, -1, -2, -3, -4, -5] + # 4.downto(5) {|i| fail 'Cannot happen' } # => 4 + # + # With no block given, returns an Enumerator. + def downto to + Primitive.attr! :inline_block + unless defined?(yield) + return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 1, &to, int_downto_size)' + end + + from = self + while from >= to + yield from + from = from.pred + end + end + # call-seq: # to_i -> self # |