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

ruby-changes:30172

From: glass <ko1@a...>
Date: Mon, 29 Jul 2013 14:58:47 +0900 (JST)
Subject: [ruby-changes:30172] glass:r42224 (trunk): * hash.c (rb_hash_assoc): performance improvement by replacing

glass	2013-07-29 14:58:36 +0900 (Mon, 29 Jul 2013)

  New Revision: 42224

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

  Log:
    * hash.c (rb_hash_assoc): performance improvement by replacing
      compare function in RHASH(hash)->ntbl->type temporarily.

  Modified files:
    trunk/ChangeLog
    trunk/hash.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42223)
+++ ChangeLog	(revision 42224)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Jul 29 14:54:44 2013  Masaki Matsushita  <glass.saga@g...>
+
+	* hash.c (rb_hash_assoc): performance improvement by replacing
+	  compare function in RHASH(hash)->ntbl->type temporarily.
+
 Mon Jul 29 14:52:46 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/mkmf.rb (xsystem): expand environment variable in all macros not
Index: hash.c
===================================================================
--- hash.c	(revision 42223)
+++ hash.c	(revision 42224)
@@ -2115,15 +2115,34 @@ rb_hash_merge(VALUE hash1, VALUE hash2) https://github.com/ruby/ruby/blob/trunk/hash.c#L2115
 }
 
 static int
-assoc_i(VALUE key, VALUE val, VALUE arg)
+assoc_cmp(VALUE a, VALUE b)
 {
-    VALUE *args = (VALUE *)arg;
+    return !RTEST(rb_equal(a, b));
+}
+
+struct lookup2_arg {
+    VALUE hash;
+    VALUE key;
+};
+
+static VALUE
+lookup2_call(VALUE arg)
+{
+    struct lookup2_arg *p = (struct lookup2_arg *)arg;
+    return rb_hash_lookup2(p->hash, p->key, Qundef);
+}
+
+struct reset_hash_type_arg {
+    VALUE hash;
+    const struct st_hash_type *orighash;
+};
 
-    if (RTEST(rb_equal(args[0], key))) {
-	args[1] = rb_assoc_new(key, val);
-	return ST_STOP;
-    }
-    return ST_CONTINUE;
+static VALUE
+reset_hash_type(VALUE arg)
+{
+    struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
+    RHASH(p->hash)->ntbl->type = p->orighash;
+    return Qundef;
 }
 
 /*
@@ -2141,14 +2160,26 @@ assoc_i(VALUE key, VALUE val, VALUE arg) https://github.com/ruby/ruby/blob/trunk/hash.c#L2160
  */
 
 VALUE
-rb_hash_assoc(VALUE hash, VALUE obj)
+rb_hash_assoc(VALUE hash, VALUE key)
 {
-    VALUE args[2];
-
-    args[0] = obj;
-    args[1] = Qnil;
-    rb_hash_foreach(hash, assoc_i, (VALUE)args);
-    return args[1];
+    VALUE value;
+    st_table *table = hash_tbl(hash);
+    struct lookup2_arg arg;
+    struct reset_hash_type_arg ensure_arg;
+    const struct st_hash_type *orighash = table->type;
+    const struct st_hash_type assochash = {
+	assoc_cmp,
+	orighash->hash,
+    };
+
+    table->type = &assochash;
+    arg.hash = hash;
+    arg.key = key;
+    ensure_arg.hash = hash;
+    ensure_arg.orighash = orighash;
+    value = rb_ensure(lookup2_call, (VALUE)&arg, reset_hash_type, (VALUE)&ensure_arg);
+    if (value == Qundef) return Qnil;
+    return rb_assoc_new(key, value);
 }
 
 static int

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

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