summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-03-31 13:44:35 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-03-31 13:44:35 +0900
commit4c2969910f16389c0e3d602a99ded0a3d0b6e256 (patch)
tree45731e2e1826e083f62c066c64f4bd36a39aa004 /src
parent2c3530ff10f477c09145fc7ab79cd87432acccaf (diff)
downloadmruby-4c2969910f16389c0e3d602a99ded0a3d0b6e256.tar.gz
mruby-4c2969910f16389c0e3d602a99ded0a3d0b6e256.zip
Hash function to avoid funcalls if possible
Diffstat (limited to 'src')
-rw-r--r--src/hash.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/hash.c b/src/hash.c
index ed71d6ee2..26f732700 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -55,7 +55,39 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
static inline khint_t
mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
{
- return mrb_eql(mrb, a, b);
+ enum mrb_vtype t = mrb_type(a);
+
+ switch (t) {
+ case MRB_TT_STRING:
+ return mrb_str_equal(mrb, a, b);
+
+ case MRB_TT_SYMBOL:
+ if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE;
+ return mrb_symbol(a) == mrb_symbol(b);
+
+ case MRB_TT_FIXNUM:
+ switch (mrb_type(b)) {
+ case MRB_TT_FIXNUM:
+ return mrb_fixnum(a) == mrb_fixnum(b);
+ case MRB_TT_FLOAT:
+ return (mrb_float)mrb_fixnum(a) == mrb_float(b);
+ default:
+ return FALSE;
+ }
+
+ case MRB_TT_FLOAT:
+ switch (mrb_type(b)) {
+ case MRB_TT_FIXNUM:
+ return mrb_float(a) == (mrb_float)mrb_fixnum(b);
+ case MRB_TT_FLOAT:
+ return mrb_float(a) == mrb_float(b);
+ default:
+ return FALSE;
+ }
+
+ default:
+ return mrb_eql(mrb, a, b);
+ }
}
KHASH_DECLARE(ht, mrb_value, mrb_value, 1)