* 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
This commit is contained in:
nobu 2013-08-27 07:46:08 +00:00
Родитель f01cef2050
Коммит f25daa2541
4 изменённых файлов: 55 добавлений и 9 удалений

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

@ -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().

42
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++) {
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;
}
@ -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);
@ -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;
}

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

@ -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));

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

@ -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)
{