我想在这里总结一下优化性能的时候一些常见的问题。如果有写得不当之处请大家指正。
为了优化而使用非 Int
整数如 UInt
或者 UInt8
这个做法其实并不明智。大多数人可能想过使用非 Int
类型来做到数组里的indexing,如 A[0x1]
。但是这其实并不会有任何对速度的优化,而且可能会有害处。
using BenchmarkTools
dest = zeros(250); src = zeros(250);
@inline function foo!(dest, src) # 假设dest长度很小
len::UInt8 = UInt8(length(dest)) # 保证len在整个函数都是UInt8
@boundscheck @assert len == length(src)
@inbounds for i in 0x1:len
dest[i] = abs(src[i])
end
dest
end
@inline function goo!(dest, src)
len = length(dest)
@boundscheck @assert len == length(src)
@inbounds for i in 1:len
dest[i] = abs(src[i])
end
dest
end
julia> @btime @inbounds goo!($dest, $src); #用Int
24.425 ns (0 allocations: 0 bytes)
julia> @btime @inbounds foo!($dest, $src); #用UInt8
24.796 ns (0 allocations: 0 bytes)
julia> VERSION
v"1.0.0"
可以看出,用 UInt8
没有优势,但是限制了程序( dest
和 src
不能太长)。
注: @inbounds
是去除bounds check。如:
julia> koo(x) = x[1000]; koo2(x) = @inbounds x[1000];
julia> koo(src)
ERROR: BoundsError: attempt to access 250-element Array{Float64,1} at index [1000]
Stacktrace:
[1] getindex at ./array.jl:731 [inlined]
[2] koo(::Array{Float64,1}) at ./REPL[91]:1
[3] top-level scope at none:0
julia> koo2(src)
0.0
@boundscheck
告诉Julia,这个宏后面的东西在有 @inbounds
时删掉,但要注意的是有 @boundscheck
的函数前面要写 @inline
让Julia把这个函数内联。