朱莉娅,加速评估 [英] Julia, speeding up eval

查看:14
本文介绍了朱莉娅,加速评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Julia 具有访问自己的语法树的非常好的特性,这使得以编程方式生成新函数变得容易,但它比普通的 Julia 代码慢得多.

Julia has the very nice feature of having access to its own syntactic tree, which makes it easy to generate new functions programatically, but it's much slower than the normal Julia code.

例如:

julia> timing = @time for i in [1:100] tan(pi/2*rand()); end
elapsed time: 1.513e-5 seconds (896 bytes allocated)

julia> timing = @time for i in [1:100] x = pi/2*rand(); eval(:(tan(x))); end
elapsed time: 0.0080231 seconds (23296 bytes allocated)

julia> timing = @time for i in [1:100]  eval(:(tan(pi/2*rand()))); end
elapsed time: 0.017245327 seconds (90496 bytes allocated)

有没有办法让 eval 获得与普通 Julia 代码相同的速度?

Is there a way to give to eval the same speed as the normal Julia code?

我可以使用 precompile 函数稍微加快 eval 的速度,但这还不够:

I was able to slightly speed up eval using the precompile function, but that still not enough:

julia> tmp3 = :(sin(x))
:(sin(x))

julia> timing = @time for i in [1:100000] x = pi/2*rand(); eval(tmp3); end
elapsed time: 8.651145772 seconds (13602336 bytes allocated)

julia> precompile(tmp3,(Float64,Float64))

julia> timing = @time for i in [1:100000] x = pi/2*rand(); eval(tmp3); end
elapsed time: 8.611654016 seconds (13600048 bytes allocated)

@Ivarne 建议我提供有关我的项目的详细信息.好吧,我想使用 Julia 的元编程功能来计算符号导数并运行它们.

@Ivarne suggested me to provide details on my project. Well, I would like to use the meta-programming capabilities of Julia to calculate the symbolic derivatives and run them.

我写了一个函数derivative(ex::Expr,arg::Symbol),它接受一个表达式和一个参数,并返回一个新的表达式,它是ex 相对于 arg.不幸的是,生成的 Expr 计算时间太长.

I wrote a function derivative(ex::Expr,arg::Symbol) that takes and expression and an argument, and returns a new expression that is the derivative of ex with respect to arg. Unfortunately, the resulting Expr takes too long to evaluate.

作为结论,使用 @eval 而不是 eval 的性能:

as a conclusion, the performances using @eval instead of eval:

julia> timing = @time for i in [1:100000] x = pi/2*rand(); @eval(tmp3); end
elapsed time: 0.005821547 seconds (13600048 bytes allocated)

tmp3 仍然是 :(sin(x))

推荐答案

如果你需要速度,你不应该使用 eval,因为它必须做很多工作才能每次生成优化的快速代码.

If you need speed, you shouldn't use eval, because it has to do lots of work to generate optimized fast code every time.

如果你想操作表达式,你应该看看宏.它们对表达式进行操作并返回将编译一次的表达式.请参阅 http://docs.julialang.org/en/latest/manual/metaprogramming/.

If you want to manipulate expressions, you should look at macros instead. They operate on expressions and return expressions that will be compiled once. See http://docs.julialang.org/en/latest/manual/metaprogramming/.

如果您提供有关您的问题的一些详细信息,而不仅仅是对 eval 的性能测试,将更容易为您指明正确的方向.让 julia 中的 eval 更快是一个项目,而不是 StackOverflow 的问题.

If you provide some details on your problem, and not only performance testing on eval, it will be easier to point you in the right direction. Making eval in julia faster is a project, not a question for StackOverflow.

编辑:Calculus.jl 中已经有一些这样的功能,我认为最好是执行以下操作:

Edit: There is already some of that functionality in Calculus.jl, and I think it will be best if you do something like:

myexpr = :(sin(x))
myexpr_dx = derivative(myxpr)
@eval myfun(x) = $myexpr
@eval myfun_dx(x) = $myexpr_dx 

这样您就可以得到一个可以计算的函数而不是表达式.然后您可以对 myfun(x) 和 myfun_dx() 进行性能测试

So that you get a function you can evaluate instead of an expression. You can then do performance testing on myfun(x) and myfun_dx()

这篇关于朱莉娅,加速评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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