首页 > 解决方案 > 点语法导致向量加法速度降低 200 倍

问题描述

我正在试验向量加法和分量取幂的速度,当我遇到一个使用点向量化语法的奇怪结果时。

矢量化版本,

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 秒左右。为什么会出现这种情况?什么时候应该避免使用点语法以最大限度地提高性能?

标签: juliavectorization

解决方案


.+创建一个匿名函数。在 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中提到的主要内容之一。


推荐阅读