改进Julia中由字符串生成的SymPy函数的性能 [英] Improving the performance of SymPy function generated from string in Julia
本文介绍了改进Julia中由字符串生成的SymPy函数的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
fast_fct
的实现与从字符串生成的SymPy函数slow_fct
之间的性能差异约为3500倍。有没有一种方法可以加快SymPy函数的运行速度,或者是否有一种不同的、更快的方法来实现相同的速度?
请为string_to_function
函数How to lambdify a list of strings with SymPy in Julia?进行协商。
最小工作示例:
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)
推荐答案
在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
这篇关于改进Julia中由字符串生成的SymPy函数的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文