This is a followup of not-understanding-linear-growing-allocations. It took me a while to get a manageable reproducer after my first attempt of forgetting a simple const
in a type alias. The code is as follows:
using BenchmarkTools
using StaticArrays
const Vector3 = SVector{3,Float64}
abstract type AbstractShape end
struct Box <: AbstractShape
x::Float64; y::Float64; z::Float64
end
function extent(b::Box)
(Vector3(-b.x,-b.y,-b.z), Vector3(b.x,b.y,b.z))
end
struct SBox <: AbstractShape
x::Float64; y::Float64; z::Float64
end
function extent(b::SBox)
(Vector3(-b.x,-b.y,-b.z), Vector3(b.x,b.y,b.z))
end
struct Circle <: AbstractShape
r::Float64
end
function extent(c::Circle)
(Vector3(-c.r,-c.r,-c.r), Vector3(c.r,c.r,c.r))
end
struct SCircle <: AbstractShape
r::Float64
end
function extent(c::SCircle)
(Vector3(-c.r,-c.r,-c.r), Vector3(c.r,c.r,c.r))
end
struct Figure
label::String
shape::AbstractShape
end
figure = Figure("1", Box(1,1,1))
function area(fig::Figure)
lower, upper = extent(fig.shape)
sum = 0.
for i in 1:1000
sum += (upper[1]-lower[1]) * (upper[2]-lower[2])
end
sum
end
Running @time area(figure)
you get 8k allocations. With @code_warntype
you can see that the problem is with Main.extent(%1)::Any
returning Any
instead of returning Tuple{Vector3,Vector3}
. @trace from Traceur.jl
didnât help me.
To solve the problem you just need to remove (or comment) one of the overloads of extent
. For example:
struct SCircle <: AbstractShape
r::Float64
end
#function extent(c::SCircle)
# (Vector3(-c.r,-c.r,-c.r), Vector3(c.r,c.r,c.r))
#end
You then get
julia> @time area(figure)
0.000002 seconds
4000.0
The question is, why is this? If this a bug? is this a stupid thing that I have done?
Thanks very much for your help.