点语法会导致向量加法速度降低200倍

时间:2018-07-25 06:37:32

标签: julia vectorization

当我遇到dot vectorization syntax.

的一个奇怪结果时,我正在尝试矢量加法和按分量取幂的速度

非矢量化版本

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秒。为什么会发生这种情况?什么时候应该避免使用点语法来最大化性能?

1 个答案:

答案 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中提到的主要内容之一。