Skip to content

perf(viewer): share one mtime-keyed cache for the trends CSV and dir listing - #555

Open
omkargaikwad23 wants to merge 3 commits into
perf/chart-payloadfrom
perf/shared-trends-caches
Open

perf(viewer): share one mtime-keyed cache for the trends CSV and dir listing#555
omkargaikwad23 wants to merge 3 commits into
perf/chart-payloadfrom
perf/shared-trends-caches

Conversation

@omkargaikwad23

Copy link
Copy Markdown
Collaborator

trends_cache.csv was reparsed on every render by the Status tab, the
Charts tab and the run detail view, and the results directory was
relisted three times per page load. On the GCS FUSE mount each listing
costs one stat per run directory, so both scaled with the number of runs
and ran on interactions that needed neither.

Add load_trends_df and list_run_dirs, keyed on mtime, and route every
caller through them. load_summaries now builds on load_trends_df so the
CSV is parsed once rather than twice.

The frame is now shared, so the Charts filter chain uses assign() rather
than an in-place column write, which would otherwise have welded
product_dataset onto the cached object.


Stack created with GitHub Stacks CLIGive Feedback 💬

Comment thread viewer/main.py
return None

logging.info(f"Loaded {len(df)} rows from trends cache.")
_TRENDS_DF_CACHE = (mtime, df)
Comment thread viewer/main.py
d for d in os.listdir(results_dir)
if os.path.isdir(os.path.join(results_dir, d))
]
_RUN_DIRS_CACHE = (mtime, dirs)
State is serialized to the browser on every interaction, so keeping the
whole parsed trends cache in `eval_summaries` made every click upload
megabytes. Clicks that touched no data at all — switching to the Dataset
Quality tab — could stall long enough to look like a hang.

Parse into a module-level cache keyed on the trends cache mtime instead.
Click payload drops to ~1.2 KB and repeat parses go from ~122ms to ~0.07ms.

The cached list is shared across requests in a worker, so the sort now
builds a new list rather than sorting in place.
generate_d3_chart serialized every column of the trends cache into each
sandboxed iframe, including ai_summary — a ~1.7 KB LLM paragraph per run
that no chart reads. Four charts on 300 runs shipped 2.56 MB of HTML.

Project to the columns the chart actually uses: 131 KB, ~19x smaller.
job_id is kept because chart.js reads it for the hover tooltip.
…listing

trends_cache.csv was reparsed on every render by the Status tab, the
Charts tab and the run detail view, and the results directory was
relisted three times per page load. On the GCS FUSE mount each listing
costs one stat per run directory, so both scaled with the number of runs
and ran on interactions that needed neither.

Add load_trends_df and list_run_dirs, keyed on mtime, and route every
caller through them. load_summaries now builds on load_trends_df so the
CSV is parsed once rather than twice.

The frame is now shared, so the Charts filter chain uses assign() rather
than an in-place column write, which would otherwise have welded
product_dataset onto the cached object.
@omkargaikwad23
omkargaikwad23 force-pushed the perf/shared-trends-caches branch from c2dc17f to 6e43752 Compare August 20, 2026 08:23
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.

1 participant