概要
物理計算などでは、計算ルーチンに多数のパラメータを渡すことがある。
パラメータの関数への渡し方として、
- 全部引数で直接渡す
- 構造体にまとめて1つの引数で渡す
- 辞書型リストで渡す
などの方法があると思われるが、Juliaでは速度の面でどの方法が良いか試してみる。
追記(2018/10/05):
コメントをもらってやり直した結果、違う結論になったので、まとめなおしました。
[Julia] 多引数関数の速度比較 その2
↓のは計算内容にちょこちょこ不具合あります。
比較
引数渡し
julia
function f(x::Real,y::Real,z::Complex=zero(Complex),
temper::Float64=24.0)
# dummy calculation
for i in 1:100000
z = complex(x,y) + temper
end
end
@btime f(1,2.5)
2.575 ns (0 allocations: 0 bytes)
引数の何番目が何なのか、という点でちょっと読みにくいけど、
~~結局、実はこれが一番速い。~~←ウソ、ではないけど最適化でループ回ってなかったようで数字が不当でした。
構造体渡し
julia
mutable struct St
x::Real
y::Real
z::Complex
temper::Float64
end
function f2(s::St)
# dummy calculation
for i in 1:100000
s.z = complex(s.x,s.y) + s.temper
end
end
st1 = St(1,2.5,0+0im,24.0)
@btime f2(st1)
410.769 ms (700000 allocations: 22.89 MiB)
すごく遅い。
辞書リスト渡し
julia
dct = Dict(:x=>1,:y=>2.5,:z=>0+0im,:temper=>24.0)
function f3(d::Dict{Symbol,Number})
# dummy calculation
for i in 1:100000
d[:z] = complex(d[:x],d[:y]) + d[:temper]
end
end
@btime f3(dct)
29.091 ms (300000 allocations: 9.16 MiB)
まぁ遅い。
まとめ
ごく普通に引数で渡せってことですね。
ループの中で構造体メンバーや辞書リストメンバーにアクセスすると、そのオーバーヘッドが大きい、と。
まぁそうだろうなとは思いますが、速度差がここまでとは。。。
マシンスペック
julia
versioninfo()
Julia Version 1.0.1
Commit 0d713926f8 (2018-09-29 19:05 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: AMD E2-3000M APU with Radeon(tm) HD Graphics
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, generic)