summaryrefslogtreecommitdiff
path: root/numeric.rb
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2024-07-02 18:29:23 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2024-07-03 10:01:41 -0700
commitf4b313f7338f5fbe37f73aae29f70aeb474f7f5b (patch)
tree93b8697803d2ecd9553119bd44b0dab43cb09015 /numeric.rb
parentcbc40aca3ae5f139235724d4c6f9b63d0dd4e962 (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.rb29
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
#