Project

General

Profile

Actions

Feature #17135

closed

Improve performance of Integer#size method

Added by S_H_ (Shun Hiraoka) over 3 years ago. Updated almost 3 years ago.

Status:
Closed
Target version:
-
[ruby-core:99779]

Description

Integer#size seems to show improved performance when written in ruby.

benchmark:

prelude: |
  n = 42
benchmark:
  size: |
    n.size
loop_count: 20000000

result:

sh@MyComputer:~/rubydev/build$ make benchmark/integer_size.yml -e COMPARE_RUBY=~/.rbenv/shims/ruby -e BENCH_RUBY=../install/bin/ruby
# Iteration per second (i/s)

|      |compare-ruby|built-ruby|
|:-----|-----------:|---------:|
|size  |     65.749M|   87.117M|
|      |           -|     1.33x|

COMPARE_RUBY is ruby 2.8.0dev (2020-08-28T10:47:29Z master 7e1fddba4a) [x86_64-linux]. BENCH_RUBY is patched.

pull request:
https://github.com/ruby/ruby/pull/3476

Actions #1

Updated by S_H_ (Shun Hiraoka) over 3 years ago

  • Description updated (diff)
Actions #2

Updated by sawa (Tsuyoshi Sawada) over 3 years ago

  • Subject changed from Improve perfomance for Integer#size method to Improve performance of Integer#size method
  • Description updated (diff)

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to ko1 (Koichi Sasada)

The patch looks good to me. HOWEVER, let me -1 this.
Integer#size HAS to be as fast as what is proposed here, without any extra hustle like this.
@ko1 (Koichi Sasada) any idea what is preventing it from running smoothly?

Updated by S_H_ (Shun Hiraoka) over 3 years ago

I try to improve performance of Integer#size in C code with refer to TrueClass#to_s

static VALUE rb_cInteger_fix_size;

static VALUE
int_size (VALUE num)
{
    if (FIXNUM_P (num)) {
return rb_cInteger_fix_size;
    }
    else if (RB_TYPE_P (num, T_BIGNUM)) {
return rb_big_size_m (num);
    }
    return Qnil;
}

void
Init_Numeric (void)
{
    rb_cInteger_fix_size = INT2FIX (sizeof (long));
    rb_gc_register_mark_object (rb_cInteger_fix_size);
    rb_define_method (rb_cInteger, "size", int_size, 0);
}

benchmark:

prelude: |
  n = 42
benchmark: benchmark:
  size: |
    n.size
loop_count: 20000000

result:

sh@MyComputer:~/rubydev/build$ make benchmark/benchmark.yml -e COMPARE_RUBY=~/.rbenv/shims/ruby -e BENCH_RUBY=../install/bin/ruby
# Iteration per second (i/s)

|      |compare-ruby|built-ruby|
|:-----|-----------:|---------:|
|size  |     56.456M|   75.074M|
|      |           -|     1.33x|

As a result, seems to be expected improve performance.

COMPARE_RUBY is ruby 3.0.0dev (2020-09-20T11:39:25Z master 84c4c7bec8) [x86_64-linux]. BENCH_RUBY is patched.

Updated by mrkn (Kenta Murata) over 3 years ago

INT2FIX(sizeof(long) is a constant expression because INT2FIX is a constant inline function that only does some arithmetic operations. So, I guess you don't need to keep that value in rb_cInteger_fix_size global variable.

Updated by ko1 (Koichi Sasada) over 3 years ago

shyouhei (Shyouhei Urabe) wrote in #note-3:

The patch looks good to me. HOWEVER, let me -1 this.
Integer#size HAS to be as fast as what is proposed here, without any extra hustle like this.
@ko1 (Koichi Sasada) any idea what is preventing it from running smoothly?

what is the "extra hustle"?

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

ko1 (Koichi Sasada) wrote in #note-6:

shyouhei (Shyouhei Urabe) wrote in #note-3:

The patch looks good to me. HOWEVER, let me -1 this.
Integer#size HAS to be as fast as what is proposed here, without any extra hustle like this.
@ko1 (Koichi Sasada) any idea what is preventing it from running smoothly?

what is the "extra hustle"?

The proposed patch is basically Primitive.cexpr! 'int_size(self)'. Why it must be faster than rb_define_method(rb_cInteger, "size", int_size, 0)? They should at least perform identically.

Actions #8

Updated by S_H_ (Shun Hiraoka) almost 3 years ago

  • Status changed from Assigned to Closed

Applied in changeset git|3208a5df2dfb429752a130a36274464e9924cf44.


Improve perfomance for Integer#size method [Feature #17135] (#3476)

  • Improve perfomance for Integer#size method [Feature #17135]

  • re-run ci

  • Let MJIT frame skip work for Integer#size

Co-authored-by: Takashi Kokubun

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0