using BenchmarkTools
abstract type SuperType end
mutable struct TypeA <: SuperType
a::Int64
b::Int64
end
mutable struct TypeB <: SuperType
a::Int64
b::Float64
end
function Iter(objs::Vector{SuperType})
for _ in 1:1000
if rand() <= 0.5
push!(objs,TypeA(1,2))
else
push!(objs,TypeB(2,2.0))
end
end
end
function Iter(objs::Vector{TypeA})
for _ in 1:1000
if rand() <= 0.5
push!(objs,TypeA(1,2))
else
push!(objs,TypeA(2,2))
end
end
end
By defining an abstract type with two son types, I made two vectors, and tested the push!() speed.
abs = Vector{SuperType}()
@benchmark Iter(abs)
output:
BenchmarkTools.Trial:
memory estimate: 31.25 KiB
allocs estimate: 1000
--------------
minimum time: 19.018 Ī¼s (0.00% GC)
median time: 20.635 Ī¼s (0.00% GC)
mean time: 904.554 Ī¼s (89.30% GC)
maximum time: 2.039 s (100.00% GC)
--------------
samples: 5639
evals/sample: 1
and
as = Vector{TypeA}()
@benchmark Iter(as)
output:
BenchmarkTools.Trial:
memory estimate: 31.25 KiB
allocs estimate: 1000
--------------
minimum time: 19.122 Ī¼s (0.00% GC)
median time: 20.183 Ī¼s (0.00% GC)
mean time: 1.152 ms (93.90% GC)
maximum time: 2.415 s (100.00% GC)
--------------
samples: 4986
evals/sample: 1
Itās quite wired that operating the abstract type vector is not slower than the specific one. Am I doing anything wrong?
Is that because no matter what type of the vector is, what are stored are always pointers?
My best guess is that this is inning and Union splitting. The first vector is probably being stored with roughly the equivalent of a c Union. That way, each item would just be 16 bytes + a bit for which type.
The main reason is that you arenāt operating on the vector element. You just store to it so thereās no slow down from type instability.
When itās mutable, thereās also no slow down from allocation since the pointer is stored in either case. When itās immutable, thereās no slow down from allocation since the stored value is constant and the allocation is done at compile time.
I believe you should use Iter($abs) or Iter($as). I donāt think is matters much in this case though.
No!
Arrays never stores āvariableā. They always store the reference. However, if the eltype is bits type, the reference will be stored using the value instead of pointer.
Okay, thanks.
So, if the arrays always store reference, would that be slower to operating them in Julia than that in C++ when arrays stored by themselves?
Depending on what you do. Storing the value is not necessarily more efficient. FWIW, this is the whole reason you need to worry about copying in C++ā¦ Also, storing by reference does not mean storing the pointer.
No. The isbitseltype (or field type) are. This has nothing to do with the value, only the declared field type.
Humā¦ Seems I have a lot to learn. I just thought the pointer is reference. Whatās their difference BTW? Or where can I study these knowledge? In fact Iām not major in computer science or programming.