the difference between string and symbol in ruby

Do you know why rails like using symbol instead of string as key for hash?

the answer is,
when comparing symbol, it find the symbol object_id, then find the symbol,
Because there is only one copy of the same symbol in the memory in ruby.

when comparing string, it has to compare the characters in the string one by one,
Each string has its own copy, even if they are the same string.
you know this is much expensive than comparing symbol!!



1. they can be converted between each other:

"hello".to_sym  => :hello
"hello".intern   => :hello
:hello.to_s  => "hello"

"hello world" == :"hello world"

2. symbol is a constant, can't be changed.
string is a variable, can be changed.

puts "hello" << " world"
=> "hello world"

puts :hello << :"   world"
=> error, undefined method << for symbol.

sometimes, your program will rely on a string as a flag, and this flag should never change, if you use a common, string, it may be changed by mistake, for example:

status = "peace"
buggy_logger = status

print buggy_logger << "\n"

in the above code, the string status is changed by mistake.

to avoid this mistake, there are some methods:
a. use clone:

status = "peace"
buggy_logger = status.clone

by this way, if you change buggy_logger, status will not be affected.

b. use freeze:
status = "peace"
status.freeze

then it will report error if some code want to change the content of status.

c. use symbol.


3. overhead, the resource by symbol is much less.

puts "hello world".object_id
puts "hello world".object_id
puts "hello world".object_id
puts "hello world".object_id
puts "hello world".object_id

# => 3102960
# => 3098410
# => 3093860
# => 3089330
# => 3084800

you can see the object.id is different for the same string.

but for symbol:

puts :"hello world".object_id
puts :"hello world".object_id
puts :"hello world".object_id
puts :"hello world".object_id
puts :"hello world".object_id

# => 239518
# => 239518
# => 239518
# => 239518
# => 239518

They are the same.

4. there is a variable Symbol that hold all existing symbol:

puts Symbol.all_symbols.inspect

5. how to test the performance of a block of code:

require 'benchmark'

str_time = Benchmark.measure do
    10000000.times do
          "test"
     end
end.total

symbol_time = Benchmark.measure do
    10000000.times do
          :test
     end
end.total

puts "String: " + str.to_s
puts "Symbol: " + sym.to_s



你可能感兴趣的:(the difference between string and symbol in ruby)