Compilation time not vanishing on subsequent runs

Hi!

I’ve got a relatively simple piece of code that takes an 2D array (“correlation”), and gives you a radial average working outwards from the centre.

xs = range(1, 100, 100)
ys = range(1, 100, 100)
R(x, y) = (sqrt((x-51)^2 + (y-51)^2))
autocorr_distances = R.(xs, ys')

@time begin
for r in range(1, 50, 50) 
    indexes = findall(x->(x<(r+0.5) && x>(r-0.5)), autocorr_distances)
    sum = 0
    for index in indexes
        sum += correlation[index[1], index[2]]
    end
    radial_sum[trunc(Int,r)] = sum/length(indexes)
end 
end

The code itself works fine and computes what I want it to, but when I time it, it yields:

0.171478 seconds (565.92 k allocations: 26.139 MiB, 98.28% compilation time)

The roughly 98% compilation time remains even when I run the code multiple times. I am a computer science and Julia beginner, so apologies if the answer is obvious!

My guess would be the redefinition of this anonymous function, each time you run it you have to compile it again.

You’re correct, I swapped out the findall for something explicit, namely;

radial_sum[r] = Statistics.mean(correlation[r-0.5 .< autocorr_distances .< r + 0.5])

And now I get:

0.000932 seconds (651 allocations: 360.500 KiB)

Thank you!

Just for fun, I put your original code in a function:

function testit()
    xs = range(1, 100, 100)
    ys = range(1, 100, 100)
    R(x, y) = (sqrt((x-51)^2 + (y-51)^2))
    autocorr_distances = R.(xs, ys')
    correlation = rand(100,100)
    radial_sum = zeros(50)

    @time begin
        for r in range(1, 50, 50) 
            indexes = findall(x->(x<(r+0.5) && x>(r-0.5)), autocorr_distances)
            sum = 0
            for index in indexes
                sum += correlation[index[1], index[2]]
            end
            radial_sum[trunc(Int,r)] = sum/length(indexes)
        end 
    end
end

I had to add initialization for correlation and radial_sum which weren’t provided in your code. With this function definition I get the following output:

julia> testit()
  0.072925 seconds (12.87 k allocations: 833.984 KiB, 99.13% compilation time)

julia> testit()
  0.000796 seconds (350 allocations: 412.312 KiB)

julia> testit()
  0.000629 seconds (350 allocations: 412.312 KiB)

Roughly the same as your results with Statistics.mean. The moral is to beware of nonconstant globals.

I would also recommend replacing the range(1,50,50) with the simpler 1:50 which, when iterated, takes integer values, so that radial_sum[trunc(Int,r)] can be replaced by radial_sum[r]. Also, your variable name sum is not ideal, since there is a built-in sum function in Julia. Finally, since correlation is presumably a matrix of floating-point values, you should initialize summ (new name) to 0.0 (or even better to zero(eltype(correlation))) to avoid type instability.

Hi @PeterSimon,

Thank you so much for all of the advice, I really appreciate it! Your cautioning about nonconstant globals was key to solving a similar issue elsewhere in my code.

Thanks again!