JULIA / CHAPTER 12
Type stability and measured optimization
AdvancedPut numeric work behind clear function boundaries.
By the end of this chapter
- Separate configuration from a computational kernel
- Keep accumulator types appropriate for input
- Distinguish compiler inspection from performance measurement
The idea
Place substantial computation inside functions with explicit inputs. This creates a useful boundary between dynamic setup and a kernel that can specialize for concrete argument types. A type-stable return or accumulator gives the compiler more predictable information, but type stability is not a proof that a program is fast. Data layout, allocation, algorithm choice, and workload size still matter.
Use tools such as @code_warntype to investigate inference and measure representative calls after compilation warm-up. Inspecting inferred types does not measure elapsed time, and a first call may include compilation work that later calls avoid. Avoid changing a clear algorithm solely to remove a harmless annotation in a report. Establish correctness, identify a measured bottleneck, and compare equivalent computations under the same conditions.
function total_scaled(values, scale)
total = zero(promote_type(eltype(values), typeof(scale)))
for value in values
total += value * scale
end
return total
end
println(total_scaled([1, 2, 3], 2))12
The accumulator starts in a type chosen from both inputs, and the loop performs its work inside a function with explicit arguments.
Try it yourself
Compare two correct implementations on representative input after warm-up and report allocations as well as time.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING