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

ruby-changes:42967

From: mrkn <ko1@a...>
Date: Wed, 18 May 2016 09:55:00 +0900 (JST)
Subject: [ruby-changes:42967] mrkn:r55041 (trunk): Optimize each_sum for hashes

mrkn	2016-05-18 09:54:52 +0900 (Wed, 18 May 2016)

  New Revision: 55041

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55041

  Log:
    Optimize each_sum for hashes
    
    * enum.c (enum_sum, hash_sum, hash_sum_i, enum_sum_i, sum_iter):
      Optimize for hashes when each method isn't redefined.

  Modified files:
    trunk/ChangeLog
    trunk/enum.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55040)
+++ ChangeLog	(revision 55041)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed May 18 09:52:00 2016  Kenta Murata  <mrkn@m...>
+
+	* enum.c (enum_sum, hash_sum, hash_sum_i, enum_sum_i, sum_iter):
+	  Optimize for hashes when each method isn't redefined.
+
 Wed May 18 09:14:00 2016  Kenta Murata  <mrkn@m...>
 
 	* enum.c (enum_sum, int_range_sum): Extract int_range_sum from
Index: enum.c
===================================================================
--- enum.c	(revision 55040)
+++ enum.c	(revision 55041)
@@ -13,6 +13,8 @@ https://github.com/ruby/ruby/blob/trunk/enum.c#L13
 #include "ruby/util.h"
 #include "id.h"
 
+#include <assert.h>
+
 VALUE rb_mEnumerable;
 
 static ID id_next;
@@ -3569,18 +3571,17 @@ struct enum_sum_memo { https://github.com/ruby/ruby/blob/trunk/enum.c#L3571
     int float_value;
 };
 
-static VALUE
-enum_sum_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
+static void
+sum_iter(VALUE i, struct enum_sum_memo *memo)
 {
-    struct enum_sum_memo *memo = (struct enum_sum_memo *)args;
+    assert(memo != NULL);
+
     long n = memo->n;
     VALUE v = memo->v;
     VALUE r = memo->r;
     double f = memo->f;
     double c = memo->c;
 
-    ENUM_WANT_SVALUE();
-
     if (memo->block_given)
         i = rb_yield(i);
 
@@ -3662,10 +3663,32 @@ enum_sum_iter_i(RB_BLOCK_CALL_FUNC_ARGLI https://github.com/ruby/ruby/blob/trunk/enum.c#L3663
     memo->r = r;
     memo->f = f;
     memo->c = c;
+}
 
+static VALUE
+enum_sum_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
+{
+    ENUM_WANT_SVALUE();
+    sum_iter(i, (struct enum_sum_memo *) args);
     return Qnil;
 }
 
+static int
+hash_sum_i(VALUE key, VALUE value, VALUE arg)
+{
+    sum_iter(rb_assoc_new(key, value), (struct enum_sum_memo *) arg);
+    return ST_CONTINUE;
+}
+
+static void
+hash_sum(VALUE hash, struct enum_sum_memo *memo)
+{
+    assert(RB_TYPE_P(hash, T_HASH));
+    assert(memo != NULL);
+
+    rb_hash_foreach(hash, hash_sum_i, (VALUE)memo);
+}
+
 static VALUE
 int_range_sum(VALUE beg, VALUE end, int excl, VALUE init)
 {
@@ -3743,7 +3766,11 @@ enum_sum(int argc, VALUE* argv, VALUE ob https://github.com/ruby/ruby/blob/trunk/enum.c#L3766
         }
     }
 
-    rb_block_call(obj, id_each, 0, 0, enum_sum_iter_i, (VALUE)&memo);
+    if (RB_TYPE_P(obj, T_HASH) &&
+            rb_method_basic_definition_p(CLASS_OF(obj), id_each))
+        hash_sum(obj, &memo);
+    else
+        rb_block_call(obj, id_each, 0, 0, enum_sum_i, (VALUE)&memo);
 
     if (memo.float_value) {
         return DBL2NUM(memo.f);

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

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