バージョン
- Ruby 2.7.0
本題
カンマ区切りの文字列の最初のデータを取得する方法として、素直に書くと次の通り
str.split(',')[0]
でも、これだと[0]
以降のデータは捨てているので、折角コスト(処理時間)を掛けて作ったデータなのにが完全にいらない子になる。
いらないデータを作らない最小の方法はないだろうか、と考えた時に、次の2つの方法が考えられる。
方法1 splitの第2引数を指定する。
splitの第2引数を指定すると、データを最高何分割するかどうかを指定できる。たとえば、2
を指定すると、データを2分割するので次のようになる。
'a,b,c,d'.split(',', 2)
# => ["a", "b,c,d"]
これなら、2つの文字列しか作られない。
方法2 partitionメソッドの使用
String#partitionは最初に現れる引数の文字列で分割した結果を、長さ3の配列で返してくれる。
'a,b,c,d'.partition(',')
# => ["a", ",", "b,c,d"]
これも使わない文字列を過剰に生成しないので無駄が少ない。
どっちのほうが早いか
速度の面でのみ比較する。
require 'benchmark_driver'
Benchmark.driver do |x|
x.prelude <<~EOT
s = 'aaaaaaaaaaaaaa,'*100000
EOT
x.report 'partition', "s.partition(',').first"
x.report 'split', "s.split(',', 2).first"
end
Warming up --------------------------------------
partition 3.333M i/s - 3.435M times in 1.030398s (299.99ns/i)
split 2.966M i/s - 2.978M times in 1.003826s (337.13ns/i)
Calculating -------------------------------------
partition 2.709M i/s - 10.000M times in 3.691628s (369.15ns/i)
split 2.263M i/s - 8.899M times in 3.931472s (441.81ns/i)
Comparison:
partition: 2708922.5 i/s
split: 2263415.8 i/s - 1.20x slower
ということなので、split
よりもpartition
を使う方が早いのかもしれない。
大量に使うことが無いのであれば気にしないけど・・。