ruby ハッシュのキー名を文字列とシンボルの違い

# 前書き.  
ハッシュのキー名は文字列の方がいいのかシンボルで描くのがいいのか新しい気づきがあったので記事に残します。
ruby学習者の参考になれば幸いです.

# 記事の対象者.  
rubyの文法少し知っている方.   
rails tutorial４章まで進んでいる方.   
rubyの文法を少し詳しく知りたい方.  

# 目次  
1.ハッシュのキーとは.  
2.ハッシュのキー名を文字列にする場合とシンボルにする場合の違い.  
3.実際に処理速度を測ってみた.   
4.コンピュータはどのようにデータを管理しているかについて.  


# ハッシュのキーとは.
⇨バリューを取得するために必要なもの.  
ハッシュの書き方3つ.   
１つ目キーに文字列を使う.   
```
変数　＝　{ キー　=> バリュー}
変数[キー]⇨バリュー出力. 
favorite_food = { "food" =>"ラーメン"}
puts favorite_food["food"]　/ラーメンと出力

```

２つ目キーに数字を使う.  
```
変数　＝　{ キー =>　 バリュー}
変数[キー]⇨バリュー出力. 
favorite_food = { 1 =>"ラーメン"}
puts favorite_food[1]　/ラーメンと出力

```

３つ目キーにシンボルを使う. 
``` 
変数　＝　{ キー =>　 バリュー}
変数[キー]⇨バリュー出力. 
favorite_food = { food:  "ラーメン"}
puts favorite_food[:food]　/ラーメンと出力
```

# 2.ハッシュのキー名を文字列にする場合とシンボルにする場合の違い. 
favorite_food[:food]とfavorite_food[”food”]でバリューを取得するときの違い.  
⇨私の最初の２つの書き方の違いは
「シンボルで取得する方が書き方楽でいいやん」ぐらいでした. 
ただ２つの間に明確の違いがありました。
それは⇨「処理速度でした」.  
結論.  
 シンボルで取得した方が処理が早い.  
文字列は遅いです.  

# 3.実際に処理速度を測ってみた.  
⇨rubyのgemに処理速度を測るbenchmark-ipsというgemがあります.  
使い方やインストール方法は割愛します. 
rubyファイル内で処理をくらべたい内容を記述します. 
↓今回の場合でいうと.  
"apple"を取得するとき「シンボル」「文字列」「数字」でアクセスした場合の速度の違いをくらべています. 
```
require 'benchmark/ips'
STARTING_HASH = { "fruit" => "apple"}
SYMBOL_HASH = { :fruit => "apple"}
INTEGER_HASH = { 1 => "apple"}
Benchmark.ips do |x|
  x.report("string") { STARTING_HASH["apple"]}
  x.report("symbol") { SYMBOL_HASH[:apple]}
  x.report("integer") { INTEGER_HASH[1]}
  x.compare!
end
```
 実験結果↓.  
![スクリーンショット 2023-02-01 17.38.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/91912748-8ad4-0df3-5748-083c93cb2c58.png)

実験結果の見方（細かいとこは今回気にしません).  
⇨数字が大きい方が処理が早いことを表しています。  
１位数字.  
2位シンボル.  
3位文字列.  

この処理の速さの差はどこから来ているのでしょうか？
コンピュータのデータの管理の仕方が関係しています。

# 4.コンピュータはどのようにデータを管理しているかについて.  
イメージで言うと棚の中にデータを入れるイメージ. 
![sandan_box_14822.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/66fc2f60-d2a4-150b-2138-c19beb5a0723.jpeg)

# どこにデータを入れる？
文字列⇨毎回ランダムの引き出しの中にデータを入れる.  
数字→どの引き出しにデータを入れるか決まっている.  
シンボル→どの引き出しにデータを入れるか決まっている.  


実際にデータがどこに入るかみてみよう.  
例　数字の１に.object_idメソッドをつけてエンター押すと３と返ってくる。.object_idメソッドはデータの場所を教えてくれるメソッド. 
この３の意味は「データが格納されている場所のこと」要は３番に１という情報を格納している。
タンスで言うと上の引き出しから１、２、３番のように引き出しに番号がついていたとすると
１という情報を取得したい場合はいつでも３番（一番下の引き出し）に１が入っている。
![スクリーンショット 2023-02-01 17.36.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/d0752eba-593e-b4b8-0096-170aab90cfd5.png)
 
シンボルも同様に同じ場所に格納されていることがわかる.  
![スクリーンショット 2023-02-01 17.36.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/40aaa6cc-8201-b3e9-a427-2b1d18a783ee.png)


ただ文字列の場合だけ毎回違う引き出しにデータが格納されるのでデータを探す時間がかかり結果処理が遅い. 
![スクリーンショット 2023-02-01 17.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602256/291119fb-37db-35c3-08c5-e35c41afd983.png)


疑問. 
シンボルと数字ではなぜ数字の方が処理速度が速いの？
⇨コンピュータは本来数字しかわからないのでシンボルのように:fruitとアクセスされても理解できず一度fruitを数字に変換してからどこにデータがあるのか探すのでシンボルの方が処理が遅い.  
疑問２じゃあ数値でアクセスできるようにコードを書いたほうが良くね?   
⇨人間が理解しにくくなる. 
やろうとしていることはわかるけど人間が理解しにくい。  

例 
```
favorite_food = { 1 => "ラーメン"}
favorite_food[1] /ラーメン

```

まとめ. 
文字列でバリューにアクセスしようとするのは人間にとってわかりやすいがコンピュータにとって理解しにくい.  
数字はコンピュータには理解しやすいが人間にわかりにくい.  
シンボルは人間にわかりやすく、シンボルは数値として処理されるのでコンピュータにとっても理解しやすい. 
のでシンボルでアクセスするのが主流