The Performance Tips has a section on using @time
to identify excessive allocations and reduce usage of untyped global variables. When allocations were technically eliminated, it points out that “the 1 allocation [of 16 bytes] seen is from running the @time
macro itself in global scope” and demonstrates that running @time
in a function call removes that lingering allocation.
But what explains that allocation being present when running @time
in a let
block that doesn’t use untyped global variables? Here’s an adaptation of that section demonstrating this (v1.8.5):
x = rand(1000);
function sum_arg(y)
s = zero(eltype(y))
for i in y s += i end
return s
end
time_sum(y) = @time sum_arg(y)
@time sum_arg(x) # 9.62k alloc, 520.796 KiB
@time sum_arg(x) # 1 alloc, 16 bytes
let y = x
@time sum_arg(y) # 1 alloc, 16 bytes????
end
time_sum(x) # 0 alloc
An annotation @time sum_arg(x::Vector{Float64})
, let y::Vector{Float64}=x
, or let y=x::Vector{Float64}
would remove the 1 allocation. It makes sense for the globally scoped call, but I expected the let
block to infer y
’s type already because let
blocks generally seem to do some type inference optimizations, though not as well as function
s.