Project Story: Experimenting with Code

metrics, timing, visualizers

4.  Experimenting with Code

Before using AI to help write code you need a place to run and measure code quickly. This chapter sets up a scratch arena - a lightweight, disposable workspace where experiments are cheap, failure is expected, and anything worth keeping gets promoted to a real project.
Why isolate experiments?
  1. Real projects carry pressure: tests must pass, CI must be green, code review is watching. A scratch arena has none of that friction.
  2. Separating “trying something” from “building something” keeps both cleaner - the real project stays stable while experiments fail fast.
  3. A version-controlled scratch space lets you revisit a dead end without losing it, and compare two approaches side by side.
  4. Measuring code from the start - lines, complexity, timing - builds the habit of treating metrics as feedback, not bureaucracy.

4.1  Code Metrics

Metrics tools answer “how big?” and “how complex?” before and after a change. Run them at the start of a session to establish a baseline, and after each significant change to see what moved. code_metrics.py (in track) - Reports line counts, function counts, and blank/comment ratios per file. Good for tracking growth of a scratch project over sessions. tokei - Cross-language line counter; breaks down by language and file type. Run at the sandbox root to see the whole arena at a glance.
cargo install tokei
scc (Sloc Cloc and Code) - Like tokei but adds estimated complexity and cost columns. Useful when comparing equivalent programs across languages.
cargo install scc
radon (Python) - Cyclomatic complexity and maintainability index per function.
pip install radon  -  run: radon cc -s script.py
cargo clippy (Rust) - Catches non-obvious mistakes and style issues that the compiler misses. Treat warnings as a quality signal, not a failure condition. cppcheck (C++) - Static analysis for undefined behavior, memory issues, and style.
cppcheck --enable=all main.cpp

4.2  Performance and Timing

hyperfine - Cross-language wall-clock benchmarker. Runs a command N times, warms the cache, and reports mean ± stddev with outlier detection. Use it to compare the same algorithm across languages directly.
cargo install hyperfine
hyperfine './out input.txt' 'python script.py input.txt'
tf_timer.py / pa_timer.py (in track) - Purpose-built timing wrappers for TextFinder and PageValidator. Model these for any experiment that needs repeated-run averaging. Python cProfile (built-in) - Function-level profiler; no install needed. Pairs with snakeviz (see section 4.3) for visual output.
python -m cProfile -s cumtime script.py
cargo flamegraph (Rust) - Generates a flame graph SVG showing where CPU time actually goes. Requires perf (Linux) or DTrace (macOS); works in WSL on Windows.
cargo install flamegraph
BenchmarkDotNet (C#) - Add as a NuGet package; annotate methods with [Benchmark]. Produces statistically rigorous tables with warmup and GC stats.

4.3  Visualizers

CodeWebifier (in track) - Converts source files to syntax-highlighted HTML for display in the site. Run it on any experiment worth keeping to publish it. snakeviz (Python) - Browser-based flame graph for cProfile output.
pip install snakeviz
python -m cProfile -o out.prof script.py
snakeviz out.prof           # opens browser with interactive flame graph
graphviz / dot - Renders dependency graphs, state machines, and call graphs as SVG. Most build tools can emit .dot format (cargo metadata, doxygen).
winget install graphviz
cargo doc --open (Rust) - Not just for publishing - generated doc pages are the fastest way to browse the public API of any crate you add to an experiment. VS Code extensions worth installing for the arena:
  • Error Lens - inline error messages next to the offending line
  • GitLens - last-edit blame inline; useful for tracking what changed in scratch
  • CodeMetrics (kisstkondoros) - per-function complexity score in the editor gutter
  • Rust Analyzer - essential for Rust; includes inlay type hints
  • clangd - C++ language server with inline diagnostics and completions

4.4  A Typical Session Flow

A short ritual at the start and end of each session keeps the arena useful:
  1. Create or reset the current project in Code/Projects.
  2. Write the simplest version that compiles and runs.
  3. Run metrics: tokei and code_metrics.py for a baseline snapshot.
  4. Iterate: change one thing, re-run, compare metrics and timing.
  5. If the result is worth keeping, run CodeWebifier and move it to a named folder; otherwise delete and move on.
  6. Add one line to notes/[new project name].md: what you tried, what you learned.

4.5  References

Resource Description
hyperfine Cross-platform benchmarking tool for command-line programs.
tokei Fast, accurate code line counter with language breakdown.
scc Line counter with complexity and estimated cost columns.
radon Python complexity metrics: cyclomatic complexity, maintainability index.
cargo flamegraph Flame graph profiler for Rust programs.
BenchmarkDotNet Rigorous microbenchmark framework for .NET.
snakeviz Browser-based viewer for Python cProfile output.