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.
```
This commit is contained in:
Aaron Patterson 2024-07-02 18:29:23 -07:00 коммит произвёл Aaron Patterson
Родитель cbc40aca3a
Коммит f4b313f733
2 изменённых файлов: 29 добавлений и 45 удалений

Просмотреть файл

@ -5623,50 +5623,6 @@ int_downto_size(VALUE from, VALUE args, VALUE eobj)
return ruby_num_interval_step_size(from, RARRAY_AREF(args, 0), INT2FIX(-1), FALSE); return ruby_num_interval_step_size(from, RARRAY_AREF(args, 0), INT2FIX(-1), FALSE);
} }
/*
* 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.
*
*/
static VALUE
int_downto(VALUE from, VALUE to)
{
RETURN_SIZED_ENUMERATOR(from, 1, &to, int_downto_size);
if (FIXNUM_P(from) && FIXNUM_P(to)) {
long i, end;
end = FIX2LONG(to);
for (i=FIX2LONG(from); i >= end; i--) {
rb_yield(LONG2FIX(i));
}
}
else {
VALUE i = from, c;
while (!(c = rb_funcall(i, '<', 1, to))) {
rb_yield(i);
i = rb_funcall(i, '-', 1, INT2FIX(1));
}
if (NIL_P(c)) rb_cmperr(i, to);
}
return from;
}
static VALUE static VALUE
int_dotimes_size(VALUE num, VALUE args, VALUE eobj) int_dotimes_size(VALUE num, VALUE args, VALUE eobj)
{ {
@ -6246,7 +6202,6 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1); rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1); rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
rb_define_method(rb_cInteger, "upto", int_upto, 1); rb_define_method(rb_cInteger, "upto", int_upto, 1);
rb_define_method(rb_cInteger, "downto", int_downto, 1);
rb_define_method(rb_cInteger, "succ", int_succ, 0); rb_define_method(rb_cInteger, "succ", int_succ, 0);
rb_define_method(rb_cInteger, "next", int_succ, 0); rb_define_method(rb_cInteger, "next", int_succ, 0);
rb_define_method(rb_cInteger, "pred", int_pred, 0); rb_define_method(rb_cInteger, "pred", int_pred, 0);

Просмотреть файл

@ -241,6 +241,35 @@ class Integer
self self
end 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: # call-seq:
# to_i -> self # to_i -> self
# #