Memory Allocation in `@time` but not in `AllocCheck.check_allocs`

Hi there, I am wondering what this is about:

In @time I see an allocation of 16 Bytes.
When using AllocCheck.check_allocs, everything is clean.

Here a code example:

using Statistics
using LinearAlgebra
using StaticArrays
using AllocCheck

xs = 1:0.1:30
ys = sin.(xs) + 0.1xs + rand(length(xs))

sumofsquares(n) = n*(n+1.0)*(2.0*n+1.0)/6.0
smooth(a, b, γ) = a + γ * (b - a)

function mytest(ys)
    # simplified implementation of https://stats.stackexchange.com/a/370175
    # x is the diagonal offset, y the percentage of local recurrence
    # we compute the slope of a simple linear regression with bias
    xs = 1:length(ys)
    x_mean = mean(xs)
    xx_mean = sumofsquares(length(xs)) / length(xs)

    n = 0.0
    y_mean = 0.0
    xy_mean = 0.0
    for (x, y) in zip(xs, ys)
        n += 1.0
        y_mean = smooth(y_mean, y, inv(n))
        xy_mean = smooth(xy_mean, x*y, inv(n))
    end
    A = SA[ 
        xx_mean x_mean
        x_mean  1.0
    ]
    b = SA[xy_mean, y_mean]
    return (A \ b)[1]  # slope
end

@time mytest(ys)  # 0.000008 seconds (1 allocation: 16 bytes)
AllocCheck.check_allocs(mytest, Tuple{Vector{Float64}})  # Any[]

(@profview_allocs seems to follow check_allocs from the second execution onwards. I saw once an allocation in @profview_allocs as a Vector{Any} within IncrementalCompact InstructionStream from the ir.jl file, but not sure about the precise mechanics which produced this)

It’s not runnable for me because smooth is missing, but this looks like compilation of a runtime dispatch with global variables, which AllocCheck skips because it’s not happening within the method call itself. The Performance Tips mention you can put the @time call inside a timing method to get rid of the allocation, but you could also make a const global like const ys2 = ys; @time mytest(ys2) or interpolate global variables into @btime mytest($ys2) if you have the extra seconds for a more robust benchmark. I’m not familiar with Chairmarks.jl, but it also supports interpolation and it seems like @b ys2 mytest accomplishes the same thing as interpolation.

1 Like

thank you so much! indeed the single allocation goes away as soon as I interpolate the global with benchmarktools :heart:
(I also added the smooth function now)