Challenge 1: Why Debug Builds Are Slower — Possible Solution ==================================================================== A debug build (cargo build, no --release) disables most of the optimizations a release build applies — specifically relevant here: - NO INLINING (or much less aggressive inlining): each call to Vec::push likely remains a genuine function call in a debug build, with real call/return overhead, rather than being inlined directly into the calling code the way an optimizing release build would do for such a small, frequently-called function. - NO/MINIMAL DEAD CODE ELIMINATION AND CODE-PATH SIMPLIFICATION: bounds checks, capacity checks, and other internal Vec bookkeeping that a release build's optimizer can sometimes prove unnecessary and eliminate (or hoist out of a loop) are generally left in place, unoptimized, in a debug build. - EXTRA DEBUGGING INFORMATION AND UNOPTIMIZED CODEGEN GENERALLY: debug builds prioritize FAST COMPILE TIMES and accurate debugging experience (real stack traces, no reordered/merged instructions that would make stepping through code in a debugger confusing) over runtime speed — this is a deliberate trade-off, not an oversight. Across 1,000 .push() calls, each of these small, individually unoptimized overheads compounds — 1,000 real function calls, 1,000 unoptimized bookkeeping checks, none of the loop-level optimizations a release build's optimizer would apply to a tight, repetitive loop like this one. The CUMULATIVE effect is that the debug build can run this loop meaningfully slower — often by a large factor — than the release build performing the exact same logical operations.