Skip to content

feat(export): add --analyze-config function-call profiler#6

Closed
julienduchesne wants to merge 1 commit into
masterfrom
julienduchesne/export-analyze-profiler
Closed

feat(export): add --analyze-config function-call profiler#6
julienduchesne wants to merge 1 commit into
masterfrom
julienduchesne/export-analyze-profiler

Conversation

@julienduchesne

Copy link
Copy Markdown
Collaborator

Summary

Add an opt-in Jsonnet function-call profiler to rtk export so it's easy to see which functions dominate an evaluation. Enable it with --analyze-config <file.json>, where the config selects how results are ranked and where they're written.

  • output_file (required), plus optional sort_by (total (default), self, calls), total_time_threshold, and self_time_threshold (both in milliseconds, default 0)
  • Report ranks functions and shows call count, inclusive total time, self time, and the defining file when known
  • Zero overhead when the flag is absent: the hot path is gated by a single relaxed atomic load

Context

The single choke point for every Jsonnet call (FuncVal::evaluate) is wrapped with enter/exit timing. Each worker thread accumulates per-function counts and timings in thread-local storage and merges into a shared aggregate once per environment evaluation, so there's no per-call locking and the parallel export path stays fast.

Inclusive ("total") time is recursion-corrected: only the outermost frame of a given function on the stack contributes, so a recursive helper isn't counted once per stack level. Without this, a deeply recursive tokenizer showed a nonsensical 277s total (far above wall-clock); after the fix its caller correctly ranks above it and the numbers reflect the real call hierarchy.

Made with Cursor

Add an opt-in Jsonnet function-call profiler to `rtk export`, enabled via
`--analyze-config <file.json>`. The config requires `output_file` and
optionally accepts `sort_by` (total/self/calls), `total_time_threshold`,
and `self_time_threshold` (milliseconds).

Profiling is gated by a single relaxed atomic, so the normal path is
unaffected. Each thread accumulates per-function call counts and timings in
thread-local storage and merges into a global aggregate once per environment
evaluation, avoiding per-call locking. Inclusive time is recursion-corrected
(only the outermost frame of a function contributes) so recursive helpers are
not multiply-counted.

Co-authored-by: Cursor <cursoragent@cursor.com>
@julienduchesne julienduchesne requested a review from a team as a code owner June 9, 2026 15:55
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Benchmark Results

Benchmark Test vs tk vs base
Diff cluster_scoped 53.95x faster equal
Diff configmap_unchanged 32.16x faster equal
Diff deployment_nested_changes 30.54x faster equal
Env List Single Inline Directory (--json) 48.48x faster equal
Env List Single Inline File (--json) 47.62x faster equal
Env List All Environments (--json) 87.24x faster equal
Eval Single Static Environment 15.74x faster equal
Eval Inline Environment File 20.22x faster equal
Eval Eval Expression - Deeply Nested Path 15.63x faster equal
Export (Full) Single Static Environment 6.7x faster equal
Export (Full) Single Inline Environment 21.01x faster equal
Export (Full) All Environments 18.82x faster equal
Export (Replace) Single Static Environment 5.81x faster equal
Export (Replace) Single Inline Environment 20.77x faster equal
Export (Replace) All Environments 27.61x faster equal
Helm Template Full Export 1.73x faster 1.22x faster
Tool Importers Count Single Lib Directory (Non-Recursive) 2.39x faster equal
Tool Importers Count Single Lib Directory (Recursive) 2.33x faster equal
Tool Importers Count Entire Lib Directory (Non-Recursive) 1.41x faster equal
Tool Importers Count Entire Lib Directory (Recursive) 1.12x faster equal
Tool Importers Global Lib File 3.14x faster equal
Tool Importers Single Env-Specific Lib File 1.59x faster equal
Tool Importers All Env-Specific Lib Files 5.29x faster equal
Tool Importers All Lib Files 5.08x faster equal
Tool Importers All Jsonnet Files 8.79x faster equal
Tool Imports Single Static Environment 3.28x faster equal
Tool Imports Single Inline Environment File 3.48x faster equal
Validate Manifests All Validations - equal
Validate Manifests Manifest Tests Only - equal
Validate Manifests Namespace Test Only - equal

Full results available in workflow artifacts.

Benchmark run on commit af3e9b4f194bfa08b317776316c41231be616680

@juliajohannesen juliajohannesen left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be better as an option that enables dynamic tracing spans? IE using the --analyze-config has the program start with a custom tracer that captures function call spans from jrsonnet?

@julienduchesne julienduchesne marked this pull request as draft June 11, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants