r = rand(10)
test1(r) = sum( t^2 for t in r )
test2(r)= sum( [t^2 for t in r] )
@code_warntype test1(r) # return type Any is inferred
@code_warntype test2(r) # return type Float64 is inferred
julia> r = rand(10^5);julia> @time test1(r)0.000246 seconds (7 allocations: 208 bytes)33375.54531253989julia> @time test2(r)0.001029 seconds (7 allocations: 781.500 KB)33375.54531253966
inner1(R, i) = sum( R[j,i] for j = 1:size(R,1) )
inner2(R, i) = sum( [R[j,i] for j = 1:size(R,1)] )
function test(R, inner)
n = [ inner(R, i)^2 for i = 1:size(R,2) ]
N = length(n)
s = 0.0
for i = 1:N, j = max(1, i-5):min(N, i+5)
s += n[i] * n[j]
end
return s
end
R = rand(10, 1000);
@time test(R, inner1)
@time test(R, inner1)
@time test(R, inner1)
# 0.002539 seconds (76.02 k allocations: 1.396 MB)
# 0.002264 seconds (76.02 k allocations: 1.396 MB)
# 0.002094 seconds (76.02 k allocations: 1.396 MB)
@time test(R, inner2)
@time test(R, inner2)
@time test(R, inner2)
# 0.000131 seconds (4.01 k allocations: 242.547 KB)
# 0.000106 seconds (4.01 k allocations: 242.547 KB)
# 0.000104 seconds (4.01 k allocations: 242.547 KB)
r = rand(10)
f(x) = x^2
test1(r) = sum( f(x) for t in r )
test2(r) = sum( [f(x) for t in r] )
@code_warntype test1(r) # return type Any is inferred
@code_warntype test2(r) # return type Float64 is inferred
g(x)::Float64 = x^2
test3(r) = sum( g(x) for t in r )
test4(r) = sum( [g(x) for t in r] )
@code_warntype test3(r) # return type Any is inferred
@code_warntype test4(r) # return type Any is inferred
since the type was not inferred the zero-element could not be created.
@time test3(r)
0.000032 seconds (4 allocations: 160 bytes)
The real problem is that eltype(t^2 for t in rand(10)) returns Any.
The real problem is that eltype(t^2 for t in rand(10)) returns Any.that is not a problem (t^2 for t in rand(10)) is a generator its element type is Any which means a pointer to something complex.
We could use type inference on the function t -> t^2 (which is buried in the generator) to determine a more specific eltype.
you can rewrite it in a more explicit way
Sorry for being slow: the input array rand(10) or the output array, the square of each element of rand(10)?
julia> (begin;println(t);t^2;end for t=1:10)
Base.Generator{UnitRange{Int64},##37#38}(#37,1:10)
julia> (begin;println(t);t^2;end for t=1:10)
Base.Generator{UnitRange{Int64},##37#38}(#37,1:10)Julia knows that the input to the generator is a UnitRange{Int64}, i.e. 1:10, so the input elements are Int64. It knows that the function being computed is t -> t^2. The compiler is smart enough that it can figure out that if t is an Int64, then t^2 is an Int64 too, because that function is type stable. So, it can figure out that the eltype of the output (i.e. the Generator) is Int64, all at compile time without actually evaluating the function.