非矢量化版本
julia> @time exp(randn(1000) + randn(1000))
几次跑步后大约需要0.001秒。从0.6开始,还会发出弃用警告。
如果我将指数函数矢量化,
julia> @time exp.(randn(1000) + randn(1000))
我的速度提高了4倍,达到了约0.00025秒。
但是,如果我同时对指数函数和向量的加法运算(两者)
,julia> @time exp.(randn(1000) .+ randn(1000))
我的速度减慢了大约0.05秒。为什么会发生这种情况?什么时候应该避免使用点语法来最大化性能?
答案 0 :(得分:1)
.+
创建一个匿名函数。在REPL中,每次都会创建此函数,并且会破坏计时结果。另外,使用全局(动态类型,即不可推断)会减慢所有示例的速度。在任何实际情况下,您的代码都将包含在函数中。当它在函数中时,仅在第一次调用该函数时才编译。示例:
> x = randn(1000); y = randn(1000);
> @time exp(x + y);
WARNING: exp(x::AbstractArray{T}) where T <: Number is deprecated, use exp.(x) instead.
Stacktrace:
[1] depwarn(::String, ::Symbol) at .\deprecated.jl:70
[2] exp(::Array{Float64,1}) at .\deprecated.jl:57
[3] eval(::Module, ::Any) at .\boot.jl:235
[4] eval_user_input(::Any, ::Base.REPL.REPLBackend) at .\REPL.jl:66
[5] macro expansion at C:\Users\Chris\.julia\v0.6\Revise\src\Revise.jl:775 [inlined]
[6] (::Revise.##17#18{Base.REPL.REPLBackend})() at .\event.jl:73
while loading no file, in expression starting on line 237
0.620712 seconds (290.34 k allocations: 15.150 MiB)
> @time exp(x + y);
0.023072 seconds (27.09 k allocations: 1.417 MiB)
> @time exp(x + y);
0.000334 seconds (95 allocations: 27.938 KiB)
>
> @time exp.(x .+ y);
1.764459 seconds (735.52 k allocations: 39.169 MiB, 0.80% gc time)
> @time exp.(x .+ y);
0.017914 seconds (5.92 k allocations: 328.978 KiB)
> @time exp.(x .+ y);
0.017853 seconds (5.92 k allocations: 328.509 KiB)
>
> f(x,y) = exp.(x .+ y);
> @time f(x,y);
0.022357 seconds (21.59 k allocations: 959.157 KiB)
> @time f(x,y);
0.000020 seconds (5 allocations: 8.094 KiB)
> @time f(x,y);
0.000021 seconds (5 allocations: 8.094 KiB)
请注意,通过将其放入函数中,它可以进行编译和优化。这是Julia Performance Tips中提到的主要内容之一。