Julia 有一个非常好的功能,可以访问自己的语法树,这使得以编程方式生成新函数变得很容易,但它比普通的 Julia 代码慢得多。
例如:
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 代码的速度相同吗?
编辑:
我能够使用以下方法稍微加快评估速度precompile
功能,但这还不够:
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)
EDIT2:
@Ivarne 建议我提供有关我的项目的详细信息。好吧,我想使用 Julia 的元编程功能来计算符号导数并运行它们。
我写了一个函数derivative(ex::Expr,arg::Symbol)
它采用 and 表达式和一个参数,并返回一个新表达式,该表达式是ex
关于arg
。不幸的是,由此产生的Expr
评估时间太长。
EDIT3:作为结论,使用的表演@eval
代替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))