Hi all,
In the code below I define two functions, f1 and f2, that take a
three-dimensional array of Float64, computes the real FFT (rfft) and loops
once over the computed values of the rfft. In f1, a lot of time is spent in
the simple for loop, and many, many bytes are allocated. In f2, very little
time is spent in the for loop, and no bytes are allocated, as would be
expected. The only difference between the two functions is "X = rfft(x)" in
f1 and "X = rfft(x) :: Array{Complex{Float64}, 3}" in f2. For both
functions, typeof(X) says that X is an Array{Complex{Float64}, 3}, so the
extra type annotation in f2 should not be necessary.
I encountered this problem in Julia version 0.3.6 and it persists in
version 0.4.0-dev+2666. In 0.4.0 the macro @code_warntype can be used to
reveal that X is of type ANY in f1 but Array{Complex{Float64}, 3} in f2.
This seems to contradict the output of typeof(X) and is very confusing to
me.
Cheers,
Emil
### Code
function f1(x :: Array{Float64, 3})
@time X = rfft(x)
println("typeof(X) = $(typeof(X))")
@time for i = 1 : length(X)
X[i] *= X[i]
end
X
end
function f2(x :: Array{Float64, 3})
@time X = rfft(x) :: Array{Complex{Float64}, 3}
println("typeof(X) = $(typeof(X))")
@time for i = 1 : length(X)
X[i] *= X[i]
end
X
end
println("Compiling...")
f1(rand(2,2,2))
f2(rand(2,2,2))
println("f1...")
f1(rand(128,128,128))
println("f2...")
f2(rand(128,128,128))
@code_warntype f1(rand(2,2,2))
@code_warntype f2(rand(2,2,2))
### Output
Compiling...
elapsed time: 0.165980813 seconds (5783476 bytes allocated)
typeof(X) = Array{Complex{Float64},3}
elapsed time: 0.008426071 seconds (319840 bytes allocated)
elapsed time: 9.8616e-5 seconds (3560 bytes allocated)
typeof(X) = Array{Complex{Float64},3}
elapsed time: 6.28e-7 seconds (0 bytes allocated)
f1...
elapsed time: 0.022922817 seconds (17042840 bytes allocated)
typeof(X) = Array{Complex{Float64},3}
elapsed time: 0.419889359 seconds (144836816 bytes allocated, 16.67% gc
time)
f2...
elapsed time: 0.023057751 seconds (17042840 bytes allocated)
typeof(X) = Array{Complex{Float64},3}
elapsed time: 0.002572673 seconds (0 bytes allocated)
[output of @code_warntype is omitted]