I tried three ways of calculating the first difference of a series. To my disappointment, the 3rd method is 100 times as slow as the other two. So, in such a case, using the first two methods are better?
using BenchmarkTools
using Random
A=randn(1000)
println("B1")
@btime B1=A[2:end]-A[1:end-1]
println("B2")
@btime B2=@view(A[2:end])-@view(A[1:end-1])
println("B3")
@btime begin
B3=Array{Float64}(undef, length(A)-1)
@inbounds @simd for i in 1:length(A)-1
B3[i]=A[i+1]-A[i]
end
end
Please mark your code as such with ``` backtick blocks so it formats nicely here
Take a look at the Performance Tips manual page and in particular the very first section: You want to ensure the code you benchmark is inside a function. Do that and it should be the fastest of all three options.
julia> function test(A)
B = Array{Float64}(undef, length(A) - 1)
@inbounds @simd for i ∈ length(A) - 1
B[i] = A[i+1] - A[i]
end
return B
end
test (generic function with 1 method)
julia> @btime test($A);
111.547 ns (1 allocation: 7.94 KiB)
But also note that B2 is pretty much the same speed if it’s in a function, too. Pre-allocating here would only be a big win if you can do it outside of your performance-critical (or benchmarked) section of code.
A=randn(1000)
function test1(A)
B1=A[2:end]-A[1:end-1]
return B1
end
function test2(A)
B2=@view(A[2:end])-@view(A[1:end-1])
return B2
end
function test3(A)
B = Array{Float64}(undef, length(A) - 1)
@inbounds @simd for i ∈ length(A) - 1
B[i] = A[i+1] - A[i]
end
return B
end
function test4(A)
B = Array{Float64}(undef, length(A) - 1)
for i ∈ length(A) - 1
B[i] = A[i+1] - A[i]
end
return B
end
Then I tested each of them using commands such as @btime test1($A). The results are:
By the way, there is a bug in the loop functions. The for i in x syntax needs something iterable (which numbers are in Julia, so the code actually runs, but the output is wrong, i.e. test1(A) == test2(A) != test3(A) != test4(A)):
julia> for i ∈ 100
println(i)
end
100
After replacing it with for i in eachindex(B) I get timings for test3 and test4 which are a lot closer to test2 and also to diff(A), which is exactly what the function does, no?