From: "Matthias Wächter" Date: 2007-10-02T19:23:48+09:00 Subject: hash key performance I am just wondering why different hash keys result in such a significantly different performance. 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 No surprise is that repeated lookup of a string as a key results in the worst performance, and using a Fixnum gives best performance. More interesting is a bulk of tests that relate to using symbols and variables for int, symbol and frozen string, all within timing accuracy. A noticable, but still small gap can be seen for a nonfrozen string in a variable. But here it comes: Using false and, even worse, nil (in either literal or variable form) is way slower (a good 20%) than using integers and symbols, even if they follow the same "immutable object" philosophy of fixed object_ids. Why is that? What's so special about false and nil to have such a degraded performance as a hash key? - Matthias