LeanProfiler

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.

  1. 3.1. Keep names stable and put variation in metadata
  2. 3.2. Carry repeated context through the loop
  3. 3.3. Keep one session around the question
  4. 3.4. Wait for worker tasks that belong to the run
  5. 3.5. Close a span only after asynchronous work finishes
  6. 3.6. Keep long captures finite
  7. 3.7. Give every memory number a precise meaning
  8. 3.8. The resulting event tree