黒木玄
2018-01-02
以下のようなコードは書かない方がよい:
L = 10^6
a = []
for i in 1:L
push!(a, rand())
end
以下のベンチマークテストの結果を見よ. (計算時間は minimum time で比較する.)
using BenchmarkTools
L = 10^6
a = []
@benchmark for i in 1:L
push!(a, rand())
end
BenchmarkTools.Trial: memory estimate: 76.28 MiB allocs estimate: 3998980 -------------- minimum time: 182.674 ms (0.00% GC) median time: 198.829 ms (0.00% GC) mean time: 463.833 ms (55.69% GC) maximum time: 1.221 s (83.63% GC) -------------- samples: 11 evals/sample: 1
function f(L)
a = []
for i in 1:L
push!(a, rand())
end
return a
end
L = 10^6
@benchmark a = f(L)
BenchmarkTools.Trial: memory estimate: 24.26 MiB allocs estimate: 1000020 -------------- minimum time: 52.984 ms (65.40% GC) median time: 57.755 ms (66.24% GC) mean time: 61.256 ms (67.04% GC) maximum time: 134.872 ms (80.94% GC) -------------- samples: 82 evals/sample: 1
同一のコードを函数にするだけで3倍以上速くなり, 使用メモリも3分の1になった.
function g(L)
a = Float64[]
for i in 1:L
push!(a, rand())
end
return a
end
L = 10^6
@benchmark a = g(L)
BenchmarkTools.Trial: memory estimate: 9.00 MiB allocs estimate: 20 -------------- minimum time: 9.793 ms (0.00% GC) median time: 10.989 ms (0.00% GC) mean time: 11.735 ms (6.81% GC) maximum time: 23.503 ms (26.00% GC) -------------- samples: 403 evals/sample: 1
配列の要素の型Float64を指定するだけでさらに5倍以上速くなり, 使用メモリが37%に減った.
function h(L)
a = Array{Float64}(L)
for i in 1:L
a[i] = rand()
end
return a
end
L = 10^6
@benchmark a = h(L)
BenchmarkTools.Trial: memory estimate: 7.63 MiB allocs estimate: 2 -------------- minimum time: 3.927 ms (0.00% GC) median time: 4.670 ms (0.00% GC) mean time: 5.687 ms (21.55% GC) maximum time: 13.477 ms (38.01% GC) -------------- samples: 876 evals/sample: 1
配列を一挙に確保することによってさらに2倍以上速くなり, 使用メモリも少し減った.
L = 10^6
@benchmark a = rand(L)
BenchmarkTools.Trial: memory estimate: 7.63 MiB allocs estimate: 2 -------------- minimum time: 2.258 ms (0.00% GC) median time: 2.788 ms (0.00% GC) mean time: 3.687 ms (27.37% GC) maximum time: 8.973 ms (52.78% GC) -------------- samples: 1353 evals/sample: 1
組み込み函数はさらに速い.