8000 move Integer#downto to Ruby · ruby/ruby@f4b313f · GitHub
[go: up one dir, main page]

Skip to content

Commit f4b313f

Browse files
committed
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 786cf9d) [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 786cf9d) +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. ```
1 parent cbc40ac commit f4b313f

File tree

2 files changed

+29
-45
lines changed

2 files changed

+29
-45
lines changed

numeric.c

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5623,50 +5623,6 @@ int_downto_size(VALUE from, VALUE args, VALUE eobj)
56235623
return ruby_num_interval_step_size(from, RARRAY_AREF(args, 0), INT2FIX(-1), FALSE);
56245624
}
56255625

5626-
/*
5627-
* call-seq:
5628-
* downto(limit) {|i| ... } -> self
5629-
* downto(limit) -> enumerator
5630-
*
5631-
* Calls the given block with each integer value from +self+ down to +limit+;
5632-
* returns +self+:
5633-
*
5634-
* a = []
5635-
* 10.downto(5) {|i| a << i } # => 10
5636-
* a # => [10, 9, 8, 7, 6, 5]
5637-
* a = []
5638-
* 0.downto(-5) {|i| a << i } # => 0
5639-
* a # => [0, -1, -2, -3, -4, -5]
5640-
* 4.downto(5) {|i| fail 'Cannot happen' } # => 4
5641-
*
5642-
* With no block given, returns an Enumerator.
5643-
*
5644-
*/
5645-
5646-
static VALUE
5647-
int_downto(VALUE from, VALUE to)
5648-
{
5649-
RETURN_SIZED_ENUMERATOR(from, 1, &to, int_downto_size);
5650-
if (FIXNUM_P(from) && FIXNUM_P(to)) {
5651-
long i, end;
5652-
5653-
end = FIX2LONG(to);
5654-
for (i=FIX2LONG(from); i >= end; i--) {
5655-
rb_yield(LONG2FIX(i));
5656-
}
5657-
}
5658-
else {
5659-
VALUE i = from, c;
5660-
5661-
while (!(c = rb_funcall(i, '<', 1, to))) {
5662-
rb_yield(i);
5663-
i = rb_funcall(i, '-', 1, INT2FIX(1));
5664-
}
5665-
if (NIL_P(c)) rb_cmperr(i, to);
5666-
}
5667-
return from;
5668-
}
5669-
56705626
static VALUE
56715627
int_dotimes_size(VALUE num, VALUE args, VALUE eobj)
56725628
{
@@ -6246,7 +6202,6 @@ Init_Numeric(void)
62466202
rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
62476203
rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
62486204
rb_define_method(rb_cInteger, "upto", int_upto, 1);
6249-
rb_define_method(rb_cInteger, "downto", int_downto, 1);
62506205
rb_define_method(rb_cInteger, "succ", int_succ, 0);
62516206
rb_define_method(rb_cInteger, "next", int_succ, 0);
62526207
rb_define_method(rb_cInteger, "pred", int_pred, 0);

numeric.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,35 @@ def times
241241
self
242242
end
243243

244+
# call-seq:
245+
# downto(limit) {|i| ... } -> self
246+
# downto(limit) -> enumerator
247+
#
248+
# Calls the given block with each integer value from +self+ down to +limit+;
249+
# returns +self+:
250+
#
251+
# a = []
252+
# 10.downto(5) {|i| a << i } # => 10
253+
# a # => [10, 9, 8, 7, 6, 5]
254+
# a = []
255+
# 0.downto(-5) {|i| a << i } # => 0
256+
# a # => [0, -1, -2, -3, -4, -5]
257+
# 4.downto(5) {|i| fail 'Cannot happen' } # => 4
258+
#
259+
# With no block given, returns an Enumerator.
260+
def downto to
261+
Primitive.attr! :inline_block
262+
unless defined?(yield)
263+
return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 1, &to, int_downto_size)'
264+
end
265+
266+
from = self
267+
while from >= to
268+
yield from
269+
from = from.pred
270+
end
271+
end
272+
244273
# call-seq:
245274
# to_i -> self
246275
#

0 commit comments

Comments
 (0)
0