I don’t have an answer to that question, just a few observations in line with the foregoing discussion.
If the same definition for an anonymous function appears at different points in the code, they are not the same function:
julia> typeof(x -> 2x)
var"#33#34"
julia> typeof(x -> 2x)
var"#35#36"
julia> typeof(x -> 2x)
var"#37#38"
Let’s look at what happens when we use map
. Every time map
is called with different argument types, a new version of map
will be compiled. The tricky part here is that every function has it’s own type, and as you can see above, each anonymous function has its own type. So, if you call map(x -> 2x, 1:1_000_000)
multiple times, it recompiles map
every time (it’s not just the anonymous function that gets compiled). We can see this compilation going on by using @time
(on Julia 1.6+):
julia> @time map(x -> 2x, 1:1_000_000);
0.031083 seconds (48.47 k allocations: 10.478 MiB, 88.39% compilation time)
julia> @time map(x -> 2x, 1:1_000_000);
0.030761 seconds (48.47 k allocations: 10.478 MiB, 88.54% compilation time)
julia> @time map(x -> 2x, 1:1_000_000);
0.033818 seconds (48.47 k allocations: 10.478 MiB, 89.68% compilation time)
If you save the first anonymous function and reuse it, then you won’t incur the compilation cost in subsequent calls:
julia> f = x -> 2x
#9 (generic function with 1 method)
julia> @time map(f, 1:3);
0.026009 seconds (48.45 k allocations: 2.849 MiB, 99.42% compilation time)
julia> @time map(f, 1:3);
0.000011 seconds (4 allocations: 208 bytes)
julia> @time map(f, 1:3);
0.000012 seconds (4 allocations: 208 bytes)
However, you shouldn’t normally need to worry about this too much, because if you’re planning to reuse an anonymous function, it’s probably because it’s part of a larger function, in which case the larger function (including the internal map
call) will just get compiled once. I was trying to come up with a good example of that, but oddly enough I’m just getting examples where the compilation time is zero. (My guess is that it’s not zero, just very close to zero, so it doesn’t get printed.)
julia> function foo(a)
b = 2a
map(x -> 2x + b, 1:4)
end
foo (generic function with 1 method)
julia> @time foo(1);
0.000002 seconds (1 allocation: 112 bytes)
julia> @time foo(1);
0.000002 seconds (1 allocation: 112 bytes)