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/