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

ruby-changes:4261

From: ko1@a...
Date: Wed, 12 Mar 2008 01:21:16 +0900 (JST)
Subject: [ruby-changes:4261] matz - Ruby:r15751 (trunk): * enum.c (enum_zip): optimize if all arguments are arrays.

matz	2008-03-12 01:20:44 +0900 (Wed, 12 Mar 2008)

  New Revision: 15751

  Modified files:
    trunk/ChangeLog
    trunk/enum.c

  Log:
    * enum.c (enum_zip): optimize if all arguments are arrays.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15751&r2=15750&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/enum.c?r1=15751&r2=15750&diff_format=u

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15750)
+++ ChangeLog	(revision 15751)
@@ -5,6 +5,8 @@
 
 	* array.c (rb_ary_permutation): ditto.
 
+	* enum.c (enum_zip): optimize if all arguments are arrays.
+
 Tue Mar 11 19:48:09 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* numeric.c (fix_coerce): try conversion before type check.
Index: enum.c
===================================================================
--- enum.c	(revision 15750)
+++ enum.c	(revision 15751)
@@ -1347,6 +1347,36 @@
 
 
 static VALUE
+zip_ary(VALUE val, NODE *memo, int argc, VALUE *argv)
+{
+    volatile VALUE result = memo->u1.value;
+    volatile VALUE args = memo->u2.value;
+    int n = memo->u3.cnt++;
+    volatile VALUE tmp;
+    int i;
+
+    tmp = rb_ary_new2(RARRAY_LEN(args) + 1);
+    rb_ary_store(tmp, 0, enum_values_pack(argc, argv));
+    for (i=0; i<RARRAY_LEN(args); i++) {
+	VALUE e = RARRAY_PTR(args)[i];
+
+	if (RARRAY_LEN(e) < n) {
+	    rb_ary_push(tmp, Qnil);
+	}
+	else {
+	    rb_ary_push(tmp, RARRAY_PTR(e)[n]);
+	}
+    }
+    if (NIL_P(result)) {
+	rb_yield(tmp);
+    }
+    else {
+	rb_ary_push(result, tmp);
+    }
+    return Qnil;
+}
+
+static VALUE
 call_next(VALUE *v)
 {
     return v[0] = rb_funcall(v[1], id_next, 0, 0);
@@ -1423,16 +1453,25 @@
     ID conv;
     NODE *memo;
     VALUE result = Qnil;
+    int allary = Qtrue;
 
-    conv = rb_intern("to_enum");
     for (i=0; i<argc; i++) {
-	argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
+	if (TYPE(argv[i]) != T_ARRAY) {
+	    allary = Qfalse;
+	    break;
+	}
     }
+    if (!allary) {
+	conv = rb_intern("to_enum");
+	for (i=0; i<argc; i++) {
+	    argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
+	}
+    }
     if (!rb_block_given_p()) {
 	result = rb_ary_new();
     }
     memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), 0);
-    rb_block_call(obj, id_each, 0, 0, zip_i, (VALUE)memo);
+    rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
 
     return result;
 }

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

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