I am confused by the following results of @time
. I understand that the first call contains compilation overhead. But why is the second call allocate much more then the third?
julia> mutable struct M{T}; inner::T; end
julia> function doit1(o, n)
for i in 1:n
ret = o.inner
if i == n
return ret
end
end
error()
end
doit1 (generic function with 1 method)
julia> o = M(1)
M{Int64}(1)
julia> @time doit1(o, 10^1)
0.016022 seconds (15.82 k allocations: 853.133 KiB)
1
julia> @time doit1(o, 10^5)
0.004108 seconds (1.93 k allocations: 115.715 KiB)
1
julia> @time doit1(o, 10^5)
0.000243 seconds (5 allocations: 176 bytes)
1
Maybe you should use
function doit1(o::M{T}, n) where T
...
the results of @time
can fluctuate (especially for such a ‘tiny’ function)
consider @btime
from the BenchmarkTools.jl package, which should help you with that.
mutable struct M{T}; inner::T; end
function doit1(o, n)
for i in 1:n
ret = o.inner
if i == n
return ret
end
end
error()
end
o=M(1)
@time doit1(o, 10^1)
@time doit1(o, 10^5)
#the results of time fluctuate heavily
for i=1:50
@time doit1(o, 10^5)
end
#import Pkg
#Pkg.add("BenchmarkTools")
using BenchmarkTools
@btime doit1(o,10_000)
@btime doit1(o,100_000)
#@btime doit1($o,1)
#@btime doit1($o,10_000)
The time yes, but not really the allocations.
julia> @time doit1(o, 10)
0.006965 seconds (21.90 k allocations: 1.196 MiB)
1
julia> @time 10^5
0.002142 seconds (1.88 k allocations: 115.072 KiB)
100000
julia> @time doit1(o, 10^5)
0.000046 seconds (5 allocations: 176 bytes)
1
It seems that the allocations comes from compiling the 10^n
function for different literal n
.
3 Likes
It seems that the allocations comes from compiling the 10^n
function for different literal n
.
I did not understand what you said and had already wrote an answer but checked ^
documentation first, and saw:
^(x, y)
Exponentiation operator. If x is a matrix, computes matrix exponentiation.
If y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is
transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable
compile-time specialization on the value of the exponent. (As a default fallback
we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless
^ has been defined in the calling namespace.)
Would never have expected this.
1 Like