Performance Optimization

41.1 General Principles

Measure first (profile).

Compile with -d:release (or -d:danger for hot, well-tested code). Use --mm:arc/orc, LTO, --opt:speed, and -march=native via --passC.

Choose the right data structures (seq vs array, Table vs CountTable, HashSet).

41.2 Nim-Specific Tips

Avoid unnecessary copies: use sink, lent, var params, move, and openArray instead of seq params.

Preallocate: newSeqOfCap, newStringOfCap, setLen.

Use iterators instead of building intermediate seqs (mapIt chains allocate; consider zero_functional or loops).

{.inline.} for small hot procs. Use templates for zero-cost abstractions.

Disable checks locally with {.push checks: off.} in proven-safe hot loops.

Value objects over ref objects (better cache locality, no refcounting).

Mark acyclic ref types {.acyclic.}. Use {.cursor.} for non-owning refs.

Avoid exceptions in hot paths (Nim 2 uses "goto" exceptions in C, which are cheap but not free).

Compile-time precomputation with const/static.

SIMD: nimsimd, laser primitives. Use --passC:-ffast-math carefully.

Parallelize CPU-bound work (malebolgia/weave). Use async for I/O.

41.3 Inspecting Generated Code

nim c --nimcache:./cache -d:release app.nim     # read the generated C in ./cache
nim c --asm app.nim                              # keep assembly output