在 Julia 中使用 SymPy 轉換運算式的字串我注意到原生 Julia 函式的實作與從字串生成fast_fct的 SymPy 函式之間的性能差異為 ~3500 slow_fct。有沒有辦法加快 SymPy 函式的速度,或者有沒有不同的、更快的方法來實作相同的目標?
請授予如何在 Julia 中使用 SymPy 對字串串列進行lambdify?為函式string_to_function。
最小作業示例:
using SymPy
function string_to_function(fct_string)
expression = SymPy.sympify.(fct_string)
variables = free_symbols(expression)
function(args...)
subs.(expression, (variables .=> args)...)
end
end
function fast_fct(x, y, z)
return x y z
end
slow_fct = string_to_function("x y z")
基準測驗
N = 100000
@time for i in 0:N
x, y, z = rand(3)
fast_fct(x, y, z)
end
@time for i in 0:N
x, y, z = rand(3)
slow_fct(x, y, z)
end
與近似結果
>>> 0.014453 seconds (398.98 k allocations: 16.769 MiB, 40.48% gc time)
>>> 31.364378 seconds (13.04 M allocations: 377.752 MiB, 0.64% gc time, 0.41% compilation time)
uj5u.com熱心網友回復:
實際上,通過適當的基準測驗,差異甚至更高,因為您還測量了其他東西......
using BenchmarkTools
x, y, z = rand(3)
@btime fast_fct($x, $y, $z) # 4.500 ns (0 allocations: 0 bytes)
@btime slow_fct($x, $y, $z) # 162.210 μs (119 allocations: 3.22 KiB)
一些觀察:
- 我不認為這個微基準測驗有多大用處,除非你對這些非常基本的基本操作真的很感興趣。當然,直接的 Julia 方式幾乎是即時的,而 sympy 方式需要通過大量的固定計算成本。
- 如果性能很重要,請查看
Symbolics.jlJulia 中符號計算的本機實作。這應該快得多(但是,對于這樣的例子,它永遠不會接近......)。然而,它很新,而且檔案還沒有像 sympy 那樣好。
uj5u.com熱心網友回復:
為此,在lambdify. Antonello 指出 Symbolics 可能更快——他們有一個更好的版本lambdify——但這里使用@eval可能已經足夠了:
julia> @btime fast_fct(x...) setup=(x=rand(3))
86.283 ns (4 allocations: 64 bytes)
2.2829680705749293
julia> med_fct = lambdify(SymPy.sympify("x y z"))
#101 (generic function with 1 method)
julia> @btime med_fct(x...) setup=(x=rand(3))
939.393 ns (16 allocations: 304 bytes)
1.5532948656814223
julia> ex = lambdify(SymPy.sympify("x y z"), invoke_latest=false)
:(function var"##321"(x, y, z)
x y z
end)
julia> @eval asfast_fct(x,y,z) = ($ex)(x,y,z) # avoid invoke_latest call
asfast_fct (generic function with 1 method)
julia> @btime asfast_fct(x...) setup=(x=rand(3))
89.872 ns (4 allocations: 64 bytes)
1.1222502647060117
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/314090.html
