Improve performance of rb_eql()

This improvement is similar with https://github.com/ruby/ruby/pull/1552

internal.h: add declaration of rb_eql_opt() API.

vm_insnhelper.c (rb_eql_opt): add rb_eql_opt() API which provides optimized
    path for #eql? method such as rb_equal_opt().

object.c (rb_eql): optimize using rb_eql_opt() such as rb_equal().
    Array#eql? and some methods have used rb_eql() and Array#eql? will be faster
    around 20%.

    [ruby-core:80761] [Bug #13447] [Fix GH-#1589]

### Before
       user     system      total        real
   1.570000   0.000000   1.570000 (  1.569754)

### After
       user     system      total        real
   1.300000   0.000000   1.300000 (  1.303624)

### Test code
require 'benchmark'

Benchmark.bmbm do |x|
  ary1 = Array.new(1000) { rand(1000) }
  ary2 = Array.new(1000) { rand(1000) }

  x.report do
    5000000.times do
      ary1.eql?(ary2)
    end
  end

end

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58881 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
watson1978 2017-05-25 04:25:39 +00:00
parent 6e0e067de3
commit b827fdffe6
3 changed files with 23 additions and 1 deletions

View file

@ -99,7 +99,15 @@ rb_equal(VALUE obj1, VALUE obj2)
int
rb_eql(VALUE obj1, VALUE obj2)
{
return RTEST(rb_funcall(obj1, id_eql, 1, obj2));
VALUE result;
if (obj1 == obj2) return Qtrue;
result = rb_eql_opt(obj1, obj2);
if (result == Qundef) {
result = rb_funcall(obj1, id_eql, 1, obj2);
}
if (RTEST(result)) return Qtrue;
return Qfalse;
}
/*