3.Β Design the capture
The first trace separated source reading from source analysis. That was enough to locate the larger interval, but not enough to compare files, modules, or implementations. The next capture should add that context without turning every observation into a different event.
Suppose the measured loop looks like this:
for (sourcePath, fileIndex) in sourcePaths.zipIdx do let contents β readSource sourcePath let syntax β parseSource contents let declarations β analyzeSource syntax writeIndex sourcePath declarations
The useful boundaries are already visible in the program: reading, parsing, analysis, and writing. Start with those four names. A source path, module name, or iteration number describes the circumstances of one call; it should not replace the name of the work itself.
profileFromEnvironment "indexer.run" do
for (sourcePath, fileIndex) in sourcePaths.zipIdx do
withStep fileIndex do
let contents β span "source.read" (readSource sourcePath)
let syntax β span "source.parse" (parseSource contents)
let declarations β span "source.analyze" (analyzeSource syntax)
span "index.write" (writeIndex sourcePath declarations)
This hierarchy remains readable with ten files or ten thousand. Repeated calls share summary rows, while the trace still preserves every recorded file index.
- 3.1. Keep names stable and put variation in metadata
- 3.2. Carry repeated context through the loop
- 3.3. Keep one session around the question
- 3.4. Wait for worker tasks that belong to the run
- 3.5. Close a span only after asynchronous work finishes
- 3.6. Keep long captures finite
- 3.7. Give every memory number a precise meaning
- 3.8. The resulting event tree