mieki256's diary



2017/04/09() [n年前の日記]

#2 [ruby] 配列の初期化って時間がかかるのだな

昨日書いた Scale2x の処理を行う Ruby スクリプトを、もうちょっと最適化できないものかと弄っていたのだけど。

ループ内をアレコレ弄って「あまり速くならねえな」とガッカリした直後、ふと、配列の初期化はしなくてもいいんじゃないかと気が付いて。配列の確保だけするようにしてみたら処理時間が二桁減って愕然。 *1

配列の初期化って結構処理時間を食うのだな…。いやまあ、メモリを確保して中身を書き換えていくわけだから当然だろうけど。にしても、まさか条件分岐が山ほど入ってるループ処理部分より配列の初期化で時間を食ってたとは…。

測ってみた。 :

こんな感じで。環境は Windows10 x64 + Ruby 2.2.6-p396 mingw32版。
# Array.new のベンチマーク

require 'benchmark'

w, h = 512, 256

Benchmark.bm(7) do |x|

  # 最初にやってたソレ
  x.report("[][][]") do
    a = Array.new(h).map { Array.new(w).map { Array.new(4, 0) } }
  end

  # 書き方を変えてみた
  x.report("[][][]B") do
    a = Array.new(h) { Array.new(w) { Array.new(4, 0) } }
  end

  # ループを馬鹿みたいに回してみた
  x.report("loop") do
    a = []
    h.times do
      b = []
      w.times do
        b << [0, 0, 0, 0]
      end
      a << b
    end
  end

  # 初期化を省いた
  x.report("[][]") do
    a = Array.new(h).map { Array.new(w) }
  end

  # 一次元配列にしてみた
  x.report("[]") do
    a = Array.new(w * h * 4, 0)
  end

end

結果。
              user     system      total        real
[][][]    0.047000   0.000000   0.047000 (  0.049730)
[][][]B   0.047000   0.000000   0.047000 (  0.041508)
loop      0.031000   0.000000   0.031000 (  0.032914)
[][]      0.000000   0.000000   0.000000 (  0.000188)
[]        0.000000   0.000000   0.000000 (  0.000549)

配列の中身をゼロクリアするとやっぱり遅くなるようで…。多次元配列じゃなく一次元配列にしてゼロクリアしたら速くならないか、と思ったけど甘かった。でもないか。いや、しかし、多次元配列の確保より、一次元配列でゼロクリアするほうが遅いんだよな…。

ちなみに、Ruby 2.2 ではなく Ruby 2.3 でも試してみたけど、さほど違いは無く。ていうかむしろ微妙に遅くなったり。まあ、誤差かもしれないけど。

*1: もっとも、渡された配列の中身をそのまま使う形になった ―― ポインタだけを書き換えてる形になったようなものだから、元の配列の内容を弄られるとおかしなことになるけれど、それは元々そうなってたから今更だし。

以上です。

過去ログ表示

Prev - 2017/04 - Next
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project