Skip to content

Commit

Permalink
array.c: optimized equality
Browse files Browse the repository at this point in the history
* array.c (rb_ary_index, rb_ary_rindex): use optimized equality to
  improve performance.  [Feature ruby#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
  • Loading branch information
nobu committed Aug 27, 2013
1 parent f01cef2 commit f25daa2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Tue Aug 27 16:46:05 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>

* 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 <nobu@ruby-lang.org>

* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
Expand Down
42 changes: 33 additions & 9 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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++) {
if (rb_equal(RARRAY_AREF(ary, i), val))
len = RARRAY_LEN(ary);
ptr = RARRAY_RAWPTR(ary);
for (i=0; i<len; i++) {
VALUE e = ptr[i];
switch (rb_equal_opt(e, val)) {
case Qundef:
if (!rb_equal(e, val)) break;
case Qtrue:
return LONG2NUM(i);
case Qfalse:
continue;
}
len = RARRAY_LEN(ary);
ptr = RARRAY_RAWPTR(ary);
}
return Qnil;
}
Expand Down Expand Up @@ -1463,8 +1476,9 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
static VALUE
rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
{
const VALUE *ptr;
VALUE val;
long i = RARRAY_LEN(ary);
long i = RARRAY_LEN(ary), len;

if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
Expand All @@ -1477,15 +1491,25 @@ rb_ary_rindex(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");
ptr = RARRAY_RAWPTR(ary);
while (i--) {
if (rb_equal(RARRAY_AREF(ary, i), val))
VALUE e = ptr[i];
switch (rb_equal_opt(e, val)) {
case Qundef:
if (!rb_equal(e, val)) break;
case Qtrue:
return LONG2NUM(i);
if (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;
}
Expand Down
3 changes: 3 additions & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
12 changes: 12 additions & 0 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit f25daa2

Please sign in to comment.