Rubyで値を受け渡す場合、文字列よりシンボルの方が検索が速いらしい。
この検索スピードの違いは、文字列とシンボルでのオブジェクトの扱われ方が関係しているのですが、どういう事なのか調べてみました。
文字列とシンボルでのオブジェクトID
同じ名称でも文字列は別オブジェクトで、シンボルは同一オブジェクトとして扱われる特性があります。
試しに下記のようなコードを実行し、オブジェクトIDを調べてみました。
# 文字列のオブジェクトID
p 'ABC'.object_id
p 'ABC'.object_id
# シンボルのオブジェクトID
p :ABC.object_id
p :ABC.object_id
実行結果は、下記になりました。
70147189139260
70147189139060
1015588
1015588
1,2行目の文字列は、別々のIDなのに対し、3,4行目は同一のIDです。
さらに何回か実行してみると・・・
2回目
70120609515160
70120609514980
1015588
1015588
3回目
70243594897120
70243594896960
1015588
1015588
文字列は、実行の度にオブジェクトIDが変わってしまうのに対し、シンボルは、ずっと同一のオブジェクトIDを保持し続けます。
こういった特性から、文字列で検索する時は、
別オブジェクトだけど、同じ文字列なのか?といった評価の工程の後、検索する
のに対し、シンボルで検索する時は、
オブジェクトIDで一発で検索する
ので速いという事か。
*参考
Ruby の Hash キーへのアクセスで String と Symbol でどのくらいの差があるのか比較してみた
発展編 実際に使ってみた
第一引数に両替したい円の金額、第二引数に両替したい通貨の定数を入力すると両替後の金額を出すメソッド
「exchange_for_foreign_currency」を作りました。
class Exchange
# 為替レート
EXCHANGE_RATE = { 'doll' => 110, 'euro' => 125 }
def exchange_for_foreign_currency(yen, monetary_unit)
( yen / EXCHANGE_RATE[monetary_unit] )
end
end
# 実行
p Exchange.new.exchange_for_foreign_currency(1100, 'doll')
通貨の定数であるEXCHANGE_RATEのキーは文字列で書かれていますが、両替の値の参照に使うので、このままだと効率が良くありません。
次のようにシンボルで参照するようにしてあげた方が、システム的には効率が良いという事ですね。
class Exchange
# 為替レート
EXCHANGE_RATE = { doll: 110, euro: 125 }
def exchange_for_foreign_currency(yen, monetary_unit)
( yen / EXCHANGE_RATE[monetary_unit] )
end
end
# 実行
p Exchange.new.exchange_for_foreign_currency(1100, :doll)
この辺を気を付けて使おうと思いました。