Skip to content

Read a few points of an output with far less memory and time - #6

Merged
SinaHKazemi merged 1 commit into
mainfrom
faster-output-reads
Nov 9, 2026
Merged

SinaHKazemi merged 1 commit into
mainfrom
faster-output-reads

Conversation

@SinaHKazemi

Copy link
Copy Markdown
Contributor

The deployed backend runs on a 512 MB instance. With the PyPSA-Eur set it uses about 450 MB while idle and reached 497 MB after a single generation plot. A generation plot also took about 10 s. This PR fixes both causes. Results don't change.

Changes

  • mga_format.read_output: to read a few points, it used a filtered dataset scan (pq.read_table(..., filters=...)). The scan found the right row groups but buffered about 200 MB more than the rows it returned. It now looks up each point's row group from the row-group statistics (the format requires one row group per point) and reads them with ParquetFile.read_row_groups. A file without one row group per point still goes through the filter. validate_output shares the lookup.
  • mix_output: it checked the set's members against every row of the output (isin over 420,000 Arrow strings): 2.5 s for a few points of generation. It now checks against the distinct keys.

Measured on the PyPSA-Eur set (local Docker backend)

Before After
mix_output, first call, includes the read 3.22 s, peak 554 MB 0.95 s, peak 311 MB
plot_data("generation") 2.83 s, peak 615 MB 0.15 s, peak 336 MB

Testing

  • New tests check that the direct read returns the same table as a filtered scan, for points in any order, repeated points, an unknown point and an empty selection. Another test covers the fallback for a file without one row group per point.
  • The mga-format and mga-compass tests pass (162), and so do the backend's (45).

Merging redeploys the backend on Koyeb.

🤖 Generated with Claude Code

read_output read a few points through a filtered dataset scan, which
found the right row groups but buffered some 200 MB more than the rows
it returned. It now finds each point's row group from the row groups'
statistics and reads those directly; a file without one row group per
point still goes through the filter.

mix_output checked the set's members against every row of the output,
which pandas does slowly for string columns: 2.5 s for a few points of
PyPSA-Eur's generation. It now checks them against the distinct keys.

On the PyPSA-Eur set, a generation plot's peak memory falls from about
615 MB to 336 MB and its time from about 6 s to 1 s, which matters on
the 512 MB instance the server runs on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SinaHKazemi
SinaHKazemi merged commit cde8cf2 into main Nov 9, 2026
4 checks passed
@SinaHKazemi
SinaHKazemi deleted the faster-output-reads branch November 9, 2026 00:22
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