From: "Matthias Wächter" Date: 2007-10-04T06:16:24+09:00 Subject: Performance Issues with nil, true, false as Hash Keys (1.8.6) This is a followup of [ruby-talk:272146]. I was wondering why Symbols perform better as hash keys than nil, true and false. After trying different variants of a simple script, nil and false suffer about 20% performance degradation compared to Symbols. Performance leaders are literal Fixnums. It appears that hash.c is not optimized for T_NIL, T_FALSE and T_TRUE. The following patch (against 1.8.6-p110) should fix that: --- hash.c.orig 2007-10-03 22:54:34.000000000 +0200 +++ hash.c 2007-10-03 22:55:14.000000000 +0200 @@ -93,6 +93,9 @@ switch (TYPE(a)) { case T_FIXNUM: case T_SYMBOL: + case T_NIL: + case T_FALSE: + case T_TRUE: return (int)a; break; The following is from my ruby-talk post: > I have written 11 simple test cases, all using the following template: > > num=ARGV[0].to_i > > var=:key > > a={:key => "test"} > > num.times { > b=a[:key][0] > } > > Beside this test_symbol.rb variant, I replace :key in the example > above with false (test_false.rb), an integer value 1 (test_int.rb), > with nil (test_nil.rb), with "id" (test_string.rb). In six other > variants I replace the key with var, and set var to a symbol > (test_var_symbol.rb), false (test_var_false.rb), an integer value > (test_var_int.rb), nil (test_var_nil.rb), "id" (test_var_string.rb), > and "id".frozen (test_var_frozen.rb). > > > This is my performance chart using time (dual-core CPU, called with > num=30_000_000). I ran it once (dropped timing values), then three > consecutive times and added the times (which is the sort key as well): > > test_int.rb 37.029 > test_var_int.rb 37.659 > test_symbol.rb 37.773 > test_var_symbol.rb 37.785 > test_var_frozen.rb 37.852 > test_var_string.rb 40.515 > test_var_false.rb 45.468 > test_false.rb 45.687 > test_var_nil.rb 45.894 > test_nil.rb 46.068 > test_string.rb 53.032 So nil and false, both immediate and using a variable, perform equal to each other but about 20% worse than symbols and most variable-stored variants. The above patch should fix that. Objections? Other suggestions while looking at these numbers? General question: Why are symbols not in line with literal integers at the first place (37.7 vs. 37.0 s)? - Matthias