[前][次][番号順一覧][スレッド一覧]

ruby-changes:30625

From: nobu <ko1@a...>
Date: Tue, 27 Aug 2013 16:46:28 +0900 (JST)
Subject: [ruby-changes:30625] nobu:r42704 (trunk): array.c: optimized equality

nobu	2013-08-27 16:46:08 +0900 (Tue, 27 Aug 2013)

  New Revision: 42704

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42704

  Log:
    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.

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/internal.h
    trunk/vm_insnhelper.c
Index: array.c
===================================================================
--- array.c	(revision 42703)
+++ array.c	(revision 42704)
@@ -1414,8 +1414,9 @@ rb_ary_fetch(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/array.c#L1414
 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, VALU https://github.com/ruby/ruby/blob/trunk/array.c#L1427
 	}
 	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, VALU https://github.com/ruby/ruby/blob/trunk/array.c#L1476
 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, VAL https://github.com/ruby/ruby/blob/trunk/array.c#L1491
 	}
 	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;
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42703)
+++ ChangeLog	(revision 42704)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Aug 27 16:46:05 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* 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@r...>
 
 	* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
Index: internal.h
===================================================================
--- internal.h	(revision 42703)
+++ internal.h	(revision 42704)
@@ -483,6 +483,9 @@ typedef void rb_check_funcall_hook(int, https://github.com/ruby/ruby/blob/trunk/internal.h#L483
 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));
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 42703)
+++ vm_insnhelper.c	(revision 42704)
@@ -918,6 +918,18 @@ opt_eq_func(VALUE recv, VALUE obj, CALL_ https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L918
     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)
 {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]