Rubyのコードを高速にするためのメモ

More than 3 years have passed since last update.

注意: 指標にはなりますが場合によってはパフォーマンスが異なったり挙動が変わったりコードの可読性にも影響するのでちゃんとパフォーマンスを見ながら、テストしながら書きましょう。


参考

https://github.com/JuanitoFatas/fast-ruby

https://speakerdeck.com/sferik/writing-fast-ruby


メモ


  • Arrayの数を数えるならArray#sizeもしくはArray#lengthEnumerable#countを使うより速い)

  • Arrayの検索にはArray#findもしくはArray#detectArray#select.firstより速い)

  • Arrayのランダム取得にはArray#sampleArray#shuffle.firstより速い)

  • Arrayの最初の要素の取得はArray#[0]Array#firstより速い)

  • Arrayの最後の要素の取得はArray#[-1]Array#lastより速い)

  • Arrayの繰り返しはArray#eachforより速い)

  • Arrayを処理したものをflatするならArray#flat_mapArray#map.flattenより速い)

  • Arrayを逆からeachするならArray#reverse_eachArray#reverse.eachより速い)

  • Enumerableの並び替えはEnumerable#sort_by(単純なEnumerable#sortより速い)

  • mapにはSymbol.to_proc(map(&:to_s))(map { |s| s.to_s }より速い)

  • Procをcallするならyield(引数に&blockをとってcallするより速い)

  • HashのfetchにはHash#[]Hash#fetchより速い)

  • Hashの複製にはHash#[]Hash#dupより速い)

  • Hashのkeyを繰り返し処理するならHash#each_keyHash.keys.eachより速い)

  • Hashに追加するならHash#[]=Hash.merge!は遅いしHash.mergeはもっと遅い)

  • 文字列の結合には'foo' 'bar''foo'+'bar'より速い)

  • 文字列の開始と終端を調べるにはString#start_with?String#end_with?(正規表現の方が遅い)

  • 文字列の正規表現にはString#=~String#matchより速い)

  • 文字列の置き換えにはtr(String#gsubより速い)

  • 文字列の置き換えにはさらにString#[sub_string]=での置き換えが高速

  • attr_accessorがsetter、getterを自分で定義するより速い

  • 範囲に入っているかを調べるならRange#cover?Range.include?は遅い)

  • 定義されてないメソッド呼び出し確認にはrespond_to?begin...rescueで処理させると遅い)

  • メソッドは直接callする(method_missingを使うとすごく遅いし、sendも少し遅い)

他にも高速化の手法を発見したら随時追記していきたいと思います。こういう方法もあるよ等大歓迎です。