結論からいうと、配列、ハッシュ、文字列によって異なります。
配列のとき
ある条件を満たす要素数を知りたいとき→count
単に配列の要素数を知りたいとき→length, sizecountも使える
ハッシュのとき
ある条件を満たすkeyとvalueの要素数を知りたいとき→count
単にKeyとvalueの要素数を知りたいとき→length, sizecountも使える
文字列のとき
ある条件を満たす要素数を知りたいとき→count
単に文字数をしりたいとき→length, sizecountは使えないです
この結論をもとに話を進めていきます。
lengthとsize
先ほどの説明からも分かる通り、同じメソッドなんです。やってることが同じです。
実際にコードを打っても同じ結果が返ってきます。
count
countは文字列以外を除いては、lengthとsizeと同じ働きをします。書き方に多少の差はありますが、同じ動きをしてくれます。
では何が違うのか?length/sizeとcountだと処理速度が違ってきます
実際に見ていきましょう
今回は、benchmark_driver という gem を使って処理速度を測ってみます
※以下は@scivola様のコードと結果を拝借しております。
gem "benchmark_driver"
require "benchmark_driver"
Benchmark.driver do |r|
r.prelude "a = Array.new(1000){ rand }"
r.report "a.count"
r.report "a.length"
end
すると結果は、
Comparison:
a.length: 161043915.9 i/s
a.count: 33329644.2 i/s - 4.83x slower
lengthは1秒間で1B回処理なされ、countだと1秒間に10M回の処理がなされている。
なぜこのような結果が生まれてしまうのか。countというメソッドについて深堀りしていきたいとおもいます
arrayやhashでのcountというメソッドは、 Enumerableというモジュールのメソッドなのです。参考資料
そして、Enumeriableはeachを使ってメソッドが定義されているんです。
eachはN+1問題からもわかるように、不必要な値を取得してしまうことが多々あるんですね。
そのため、countはlength/sizeメソッドに比べて処理が遅いんです。
今回は、length/sizeメソッドとcountメソッドの違い、そしてcountメソッドはなぜ処理が遅いのかという部分を解説させていただきました
以上です。何か間違いがございましたら、ご教示いただけますと幸いです。
【参考文献】