改进Julia中由字符串生成的SymPy函数的性能 [英] Improving the performance of SymPy function generated from string in Julia

查看:0
本文介绍了改进Julia中由字符串生成的SymPy函数的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Julia中使用SymPy转换表达式的字符串,我注意到原生Julia函数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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆