From f25daa254146c782ca50e6fc707f8f132e896e93 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 27 Aug 2013 07:46:08 +0000 Subject: [PATCH] array.c: optimized equality * array.c (rb_ary_index, rb_ary_rindex): use optimized equality to improve performance. [Feature #8820] * vm_insnhelper.c (rb_equal_opt): optimized equality function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42704 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ array.c | 42 +++++++++++++++++++++++++++++++++--------- internal.h | 3 +++ vm_insnhelper.c | 12 ++++++++++++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2d1271afc..f855d7f733 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Aug 27 16:46:05 2013 Nobuyoshi Nakada + + * array.c (rb_ary_index, rb_ary_rindex): use optimized equality to + improve performance. [Feature #8820] + + * vm_insnhelper.c (rb_equal_opt): optimized equality function. + Tue Aug 27 16:11:05 2013 Nobuyoshi Nakada * vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF(). diff --git a/array.c b/array.c index 5a8d8dcbcd..651f45b679 100644 --- a/array.c +++ b/array.c @@ -1414,8 +1414,9 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary) static VALUE rb_ary_index(int argc, VALUE *argv, VALUE ary) { + const VALUE *ptr; VALUE val; - long i; + long i, len; if (argc == 0) { RETURN_ENUMERATOR(ary, 0, 0); @@ -1426,12 +1427,24 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary) } return Qnil; } - rb_scan_args(argc, argv, "1", &val); + rb_check_arity(argc, 0, 1); + val = argv[0]; if (rb_block_given_p()) rb_warn("given block not used"); - for (i=0; i RARRAY_LEN(ary)) { - i = RARRAY_LEN(ary); + case Qfalse: + continue; } + if (i > (len = RARRAY_LEN(ary))) { + i = len; + } + ptr = RARRAY_RAWPTR(ary); } return Qnil; } diff --git a/internal.h b/internal.h index efbf31fece..e900c42271 100644 --- a/internal.h +++ b/internal.h @@ -483,6 +483,9 @@ typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE); VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv, rb_check_funcall_hook *hook, VALUE arg); +/* vm_insnhelper.c */ +VALUE rb_equal_opt(VALUE obj1, VALUE obj2); + /* vm_method.c */ void Init_eval_method(void); int rb_method_defined_by(VALUE obj, ID mid, VALUE (*cfunc)(ANYARGS)); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 4b8b2a2334..761c830235 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -918,6 +918,18 @@ opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci) return Qundef; } +VALUE +rb_equal_opt(VALUE obj1, VALUE obj2) +{ + rb_call_info_t ci; + ci.mid = idEq; + ci.klass = 0; + ci.vmstat = 0; + ci.me = NULL; + ci.defined_class = 0; + return opt_eq_func(obj1, obj2, &ci); +} + static VALUE check_match(VALUE pattern, VALUE target, enum vm_check_match_type type) {