前書き
Rubyに置けるコードの効率性を考えてみました
現段階では小規模なコードを書いているので問題になりませんが、将来的に大規模なコードを書くときに思わぬところでボトルネックを生み出さないように訓練する一環です。
またこの記事はフィヨルドブートキャンプ内でdocsとして共有されていた題材を元にしています。
パフォーマンスの悪いコード
以下のようなプログラムを書きました
- 1から30までの整数を30個ランダムに生成し、配列として保持します
- 配列を順に出力していき、配列内の最小値、最大値の場合にそれを明示します
#!/usr/bin/env ruby def main numbers = Array.new(30) {rand (1..30) } numbers.each do |n| puts "#{n}#{":最小値です" if min_calc(numbers) == n }#{":最大値です" if max_calc(numbers) == n }" end end def min_calc(numbers) sleep 0.5 numbers.min end def max_calc(numbers) sleep 0.5 numbers.max end main
sleep
を入れているのは実行される度に処理が走っていることを実感するためです。
つまり処理の度に何回も関数を呼び出すのは、必要がなければやめたほうがいいということです。
実際このプログラムを起動してみると、かなりじれったい動作をすることが分かります
パフォーマンスの良いコード
これを変数に格納してしまい、以下のようなコードにすれば
#!/usr/bin/env ruby def main numbers = Array.new(30) {rand (1..30) } min_number = min_calc(numbers) max_number = max_calc(numbers) numbers.each do |n| puts "#{n}#{":最小値です" if min_number == n }#{":最大値です" if max_number == n }" end end def min_calc(numbers) sleep 0.5 numbers.min end def max_calc(numbers) sleep 0.5 numbers.max end main
前のコードに比べて随分実行速度が速くなるはずです。
このコードの場合はそもそもメソッドに分割する意味はないですが、分かりやすいようにメソッドはそのままにしてあります。
ループ内で重い処理はできるだけ行わないように気を付けたいですね!