Optimize Hash methods with Kernel#hash (#10160)
This commit is contained in:
parent
6f31dd495c
commit
70de3b170b
5
benchmark/hash_key.yml
Normal file
5
benchmark/hash_key.yml
Normal file
@ -0,0 +1,5 @@
|
||||
prelude: |
|
||||
obj = Object.new
|
||||
hash = { obj => true }
|
||||
benchmark: hash.key?(obj)
|
||||
loop_count: 30000000
|
18
hash.c
18
hash.c
@ -210,10 +210,26 @@ any_hash(VALUE a, st_index_t (*other_func)(VALUE))
|
||||
return (long)hnum;
|
||||
}
|
||||
|
||||
VALUE rb_obj_hash(VALUE obj);
|
||||
VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *cme, int kw_splat);
|
||||
|
||||
static st_index_t
|
||||
obj_any_hash(VALUE obj)
|
||||
{
|
||||
VALUE hval = rb_check_funcall_basic_kw(obj, id_hash, rb_mKernel, 0, 0, 0);
|
||||
VALUE hval = Qundef;
|
||||
VALUE klass = CLASS_OF(obj);
|
||||
if (klass) {
|
||||
const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, id_hash);
|
||||
if (cme && METHOD_ENTRY_BASIC(cme) && RBASIC_CLASS(cme->defined_class) == rb_mKernel) {
|
||||
// Optimize away the frame push overhead if it's the default Kernel#hash
|
||||
if (cme->def->type == VM_METHOD_TYPE_CFUNC && cme->def->body.cfunc.func == (VALUE (*)(ANYARGS))rb_obj_hash) {
|
||||
hval = rb_obj_hash(obj);
|
||||
}
|
||||
else {
|
||||
hval = rb_vm_call0(GET_EC(), obj, id_hash, 0, 0, cme, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UNDEF_P(hval)) {
|
||||
hval = rb_exec_recursive_outer_mid(hash_recursive, obj, 0, id_hash);
|
||||
|
Loading…
x
Reference in New Issue
Block a user