We can run a performance test with these two different types, depicted here:
Our benchmark test function will compute the center of all points from an array, as follows:
using Statistics: mean
function center(points::AbstractVector{T}) where T
return T(
mean(p.x for p in points),
mean(p.y for p in points))
end
In addition, we will also define a function that can be used to make an array of points for whatever type we want:
make_points(T::Type, n) = [T(rand(), rand()) for _ in 1:n]
Let's start with a PointAny type.
We will generate 100,000 points and use BenchmarkTools to measure the time:
Next, we will run the performance test for the Point type:
As we can see, there is a huge difference between the two. Using the parametric Point type is approximately 25 times faster than the one that uses Any as a field type.
What we have learned from this anti-pattern is that we should use concrete types for fields defined in composite types. It is quite easy to factor out the abstract type we want into a type parameter. Doing this allows us to gain performance benefits from concrete types without sacrificing the ability to support other data types.