Speeds up fallback to Hash#default_proc in rb_hash_aref by removing a method call
This commit is contained in:
parent
13f4f07f21
commit
592d7ceeeb
Notes:
git
2020-01-08 18:10:16 +09:00
6
benchmark/hash_defaults.yml
Normal file
6
benchmark/hash_defaults.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
prelude: |
|
||||||
|
h = Hash.new { :foo }
|
||||||
|
benchmark:
|
||||||
|
default_aref: h[1]
|
||||||
|
default_method: h.default(1)
|
||||||
|
loop_count: 1000000
|
12
hash.c
12
hash.c
@ -105,7 +105,7 @@ rb_hash_freeze(VALUE hash)
|
|||||||
VALUE rb_cHash;
|
VALUE rb_cHash;
|
||||||
|
|
||||||
static VALUE envtbl;
|
static VALUE envtbl;
|
||||||
static ID id_hash, id_yield, id_default, id_flatten_bang;
|
static ID id_hash, id_default, id_flatten_bang;
|
||||||
static ID id_hash_iter_lev;
|
static ID id_hash_iter_lev;
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
@ -1945,11 +1945,14 @@ rb_hash_rehash(VALUE hash)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_hash_default_value(VALUE hash, VALUE key)
|
rb_hash_default_value(VALUE hash, VALUE key)
|
||||||
{
|
{
|
||||||
if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
|
VALUE args[2];
|
||||||
|
if (LIKELY(rb_method_basic_definition_p(CLASS_OF(hash), id_default))) {
|
||||||
VALUE ifnone = RHASH_IFNONE(hash);
|
VALUE ifnone = RHASH_IFNONE(hash);
|
||||||
if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
|
if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
|
||||||
if (key == Qundef) return Qnil;
|
if (key == Qundef) return Qnil;
|
||||||
return rb_funcall(ifnone, id_yield, 2, hash, key);
|
args[0] = hash;
|
||||||
|
args[1] = key;
|
||||||
|
return rb_proc_call_with_block(ifnone, 2, args, Qnil);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return rb_funcall(hash, id_default, 1, key);
|
return rb_funcall(hash, id_default, 1, key);
|
||||||
@ -2124,7 +2127,7 @@ rb_hash_default(int argc, VALUE *argv, VALUE hash)
|
|||||||
if (argc == 0) return Qnil;
|
if (argc == 0) return Qnil;
|
||||||
args[0] = hash;
|
args[0] = hash;
|
||||||
args[1] = argv[0];
|
args[1] = argv[0];
|
||||||
return rb_funcallv(ifnone, id_yield, 2, args);
|
return rb_proc_call_with_block(ifnone, 2, args, Qnil);
|
||||||
}
|
}
|
||||||
return ifnone;
|
return ifnone;
|
||||||
}
|
}
|
||||||
@ -6312,7 +6315,6 @@ Init_Hash(void)
|
|||||||
#undef rb_intern
|
#undef rb_intern
|
||||||
#define rb_intern(str) rb_intern_const(str)
|
#define rb_intern(str) rb_intern_const(str)
|
||||||
id_hash = rb_intern("hash");
|
id_hash = rb_intern("hash");
|
||||||
id_yield = rb_intern("yield");
|
|
||||||
id_default = rb_intern("default");
|
id_default = rb_intern("default");
|
||||||
id_flatten_bang = rb_intern("flatten!");
|
id_flatten_bang = rb_intern("flatten!");
|
||||||
id_hash_iter_lev = rb_make_internal_id();
|
id_hash_iter_lev = rb_make_internal_id();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user