首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >改进朱莉娅中字符串生成的SymPy函数的性能

改进朱莉娅中字符串生成的SymPy函数的性能
EN

Stack Overflow用户
提问于 2021-10-06 14:25:41
回答 2查看 141关注 0票数 1

使用朱莉娅中的SymPy来转换表达式的字符串,我注意到本机Julia函数fast_fct的实现与由字符串生成的SymPy函数slow_fct之间的性能差异为3500。是否有一种方法可以加快SymPy函数的速度,还是有一种不同的、更快的方法来实现相同的功能?

请授予How to lambdify a list of strings with SymPy in Julia?函数string_to_function

最小工作实例:

代码语言:javascript
复制
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")

基准测试

代码语言:javascript
复制
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

与近似结果

代码语言:javascript
复制
>>>  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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-07 12:59:16

为此,在lambdify中有一些示例。安东内洛指出,Symbolics可能更快--他们有一个更好的lambdify版本--但是在这里使用@eval可能足够好:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2021-10-06 15:25:56

实际上,通过适当的基准测试,差别甚至更大,因为你也在测量其他的东西.

代码语言:javascript
复制
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)

几点意见:

  • 我不认为这个微基准很有用,除非你真的对这些非常基本的基本操作感兴趣。当然,直接朱莉娅方法几乎是瞬时的,它需要花费大量固定的计算费用。如果性能很重要,请查看
  • 中的符号计算的本地实现Symbolics.jl。这应该要快得多(但是,像这样的例子,它永远不会关闭.)。然而,这是非常新的,而且这个文档还没有好到可以理解的程度。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69467593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档