From: Dave Pearson Date: 2002-12-03T18:52:13+09:00 Subject: Re: Symbol class for a newbie, I'm just not getting it. :-( * Lyle Johnson : > If nothing else, it may help to reduce the amount of string allocation, > deallocation, etc. in your programs. For example, if I wrote the following > snippet in Ruby: > > allUsers.each do |userName| > if userName == "Christopher" > # found a match > end > end > > Ruby would (presumably) allocate a new (temporary) string object, with the > contents "Christopher", for each pass through the loop. It would also > perform that many character-by-character string comparisons. For a lot of > user names, that's going to be slow. In contrast, this bit of code: > > allUsers.each do |userName| > if userName.intern == :Christopher > # found a match > end > end > > would run significantly faster since the "Christopher" symbol gets added > to the symbol table once and subsequent references just point to that > entry. But wouldn't doing that intern each time in the loop hurt you more? I tested the above idea with this code: -- cut here ---------------------------------------------------------------- require "profile" def string_test( a ) a.each do |s| if s == "MMM" # Do nothing end end end def symbol_test( a ) a.each do |s| if s.intern == :MMM # Do nothing end end end a = ( "AAA" .. "ZZZ" ).collect string_test( a ) symbol_test( a ) -- cut here ---------------------------------------------------------------- and found that the symbol comparison test was slower: ,---- | 0.00 26.11 0.00 1 0.00 13620.00 Object#symbol_test | 0.00 26.11 0.00 1 0.00 7460.00 Object#string_test `---- > Also, since Symbol objects mainly consist of an index into the > symbol table, comparing symbols is very fast -- as fast as comparing two > integer values to each other. This code could be made even faster if the > "allUsers" array stored symbols directly instead of storing strings, but > you get the idea. That does make a difference but it doesn't seem to be a very significant gain, not as significant as the above paragraph might suggest: -- cut here ---------------------------------------------------------------- require "profile" def string_test( a ) a.each do |s| if s == "MMM" # Do nothing end end end def symbol_test( a ) a.each do |s| if s == :MMM # Do nothing end end end a = ( "AAA" .. "ZZZ" ).collect s = a.collect {|s| s.intern } string_test( a ) symbol_test( s ) -- cut here ---------------------------------------------------------------- Giving: ,---- | 0.00 29.43 0.00 1 0.00 7860.00 Object#symbol_test | 0.00 29.43 0.00 1 0.00 8080.00 Object#string_test `---- Am I missing something here? -- Dave Pearson http://www.davep.org/