From: Ryan Davis Date: 2008-11-24T14:39:45+09:00 Subject: [ruby-core:20066] Re: Unexpected Performance of Symbol Construction On Nov 23, 2008, at 01:11 , Kurt Stephens wrote: > http://kurtstephens.com/node/72 > > Evaluating :�foo_bar� is 1.5 to 2.5 times faster than :foo_bar. This > is > true for both Ruby 1.8.6-p287 and Ruby 1.9 trunk. The most common > means > of specifying a Symbol literal is slower than the general expression > to > create a Symbol from a String constant. for at least 1.8 (and I highly suspect 1.9 tho I'm not checking), there is literally no difference between :blah, :'blah', and :"blah" to the parser and therefor the eval loop. You can see that via parse_tree: > % parse_tree_show -u > a = :blah, :'blah', :"blah" > s(:lasgn, > :a, > s(:svalue, s(:array, s(:lit, :blah), s(:lit, :blah), > s(:lit, :blah)))) Likewise, your case with interpolation: > % parse_tree_show -u > :"foo_#{'bar'}" > s(:lit, :foo_bar) You could assign a local variable with 'bar' and do that instead for a more fair comparison: > % parse_tree_show -u > bar = "bar" > :"foo_#{bar}" > s(:block, > s(:lasgn, :bar, s(:str, "bar")), > s(:dsym, "foo_", s(:evstr, s(:lvar, :bar)))) Finally, you NEED to add a null benchmark to your measurements. When your benchmarks are coming that close to the null benchmark, you have to suspect that your experiment is flawed or your sample size is too small. I'm getting measurements at 1m samples that are only 50% more than null. And as I increase the samples, the number converges DOWN towards null. At 5m it is only 40% more. > # of iterations = 5000000 > user system total real > null_time 0.810000 0.010000 0.820000 ( 0.843928) > :foo_bar 1.140000 0.010000 1.150000 ( 1.167343) > :'foo_bar' 1.170000 0.020000 1.190000 ( 1.256334) > :"foo_bar" 1.110000 0.010000 1.120000 ( 1.191425) > :"foo_#{'bar'}" 1.130000 0.010000 1.140000 ( 1.164772) > "foo_#{'bar'}".to_sym 2.450000 0.200000 2.650000 ( 2.702624) > "foo_bar".to_sym 2.530000 0.180000 2.710000 ( 2.770743) > :"foo_#{bar}" 4.300000 0.430000 4.730000 ( 7.484217) > "foo_#{bar}".to_sym 5.040000 0.170000 5.210000 ( 5.493593) What this is really saying to me, barring the GC issue you found, is that the numbers for plain symbols don't really matter at all. They're about as low as they're gonna get. I do find it interesting that :"foo_#{bar}" is currently 40% slower than "foo_#{bar}".to_sym... I suspect there might be a minor issue there. But for the rest? *shrug* seems acceptable to me.