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