Performance is not just about how fast one operation runs; it also depends on how its cost grows. Counting every stage in a rocket collection takes time proportional to the number of stages: O(n). A constant-time operation is O(1). Doubling the collection size roughly doubles the work of a linear count. section 12.5.1
Listing 12.18 Calculating a number of stages in a staged rocket
import Base: length length(::Rocket) = 0 length(r::StagedRocket) = 1 + length(r.nextstage)
This recursive `length` method counts stages by visiting them, so its cost grows with the rocket. section 12.5.1
Sometimes the better fix is not a faster count, but telling Julia that no effective length method exists. Declaring `IteratorSize(::Type{<:Rocket}) = Base.SizeUnknown()` lets iteration machinery choose behavior suited to a collection of unknown size. That supports operations such as `collect` and `map` without requiring a costly `length` method. section 12.5.1
Types affect performance too. A value stored in a generic container can need bookkeeping for its type and memory management. Abstractly typed fields make it harder for Julia’s JIT compiler to generate optimized machine code. Parametric types can give the compiler more precise information while also restricting which values a structure accepts. section 18.0 section 18.4
Listing 18.10 Vec2D defined with abstract type fields to mimic regular dynamic languages
struct Vec2D #1
Δx::Number #2
Δy::Number #2
end
function multiply(u::Vec2D, k::Number)
Vec2D(k * u.Δx, k * u.Δy)
end
The vector-scaling example uses `Number` fields to illustrate the performance questions raised by abstract field types. section 18.4
The payoff extends to memory layout. For an array such as `Vector{Point{Int32}}`, Julia can determine the bytes needed for its elements. A more predictable layout can reduce memory fragmentation as well as improve memory use and performance. section 18.5







































