Repository navigation
perf(core): stream on-file chunks into SQLite while the parser runs - #1295
Merged
Merged
Conversation
The transcripts native now pays the same JSON hand-off dirsql does: the parser's rows piped into a process that decodes and counts them.
Each on-file invocation's output is parsed while the next one runs, and each chunk of rows is shaped and inserted as it arrives, so ingest overlaps the parser the way a shell pipe would. The transcripts speed-of-light test now passes against the fair native.
5 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1285
Fixes #1244
Batched
on-fileingest no longer trails the shell pipeline. The transcripts speed-of-light test now compares against the fair native (find projects -name '*.jsonl' -exec python3 messages.py {} + | python3 count.py), and with this change it passes, so its xfail is removed.What the profile showed
Phase timing on the transcripts fixture (4,096 files, three parser invocations, 273,067 rows / 37 MB of JSON), release build:
The parser takes about as long as it does in the native pipeline. dirsql's extra cost was that every row got parsed, shaped and inserted only after all invocations had exited. The shell pipe consumes each batch while the next one runs.
Changes
on_file::run_streaminghands each invocation's output to a parser thread while the next invocation runs.finish_buildshapes and inserts each chunk inside the same outer transaction as it arrives, so ingest overlaps the parser like a shell pipe does. Invocations stay sequential and the error precedence stays the same: an earlier invocation's bad output still outranks a later one's failure.impl ToSql for Valueborrows text and blobs instead of cloning them. Before, every string was copied on bind.SQLite insert cost on its own
For 273,067 rows / 37 MB:
sqlite3.executemanyreplay of the same rowsThe Python replay used a temp DB. Pragma variants (journal off, 64 MB cache, 64 KiB pages,
:memory:) moved it only to 0.093-0.104 s.Timings
Release build, 1-minute load under 16, minimum of at least 6 runs. The ratio is (dirsql - startup) / native.
At 2048 files dirsql passes absolute paths, so it needs two invocations where
findwith relative paths needs one. That leaves an extra interpreter start plus the last chunk's ingest exposed. Changing what argv the hook receives would change behavior, so it is out of scope. The test grows the fixture until native takes at least 1 s, which is 4096 files on this box.Red / green
db::tests::text_and_blob_values_bind_without_copyingfailed with leftOwned(Text("abc"))and rightBorrowed(Text([97, 98, 99])).--runxfailreported "dirsql 2.250s minus startup 0.038s = 2.211s, over 1.1x native 1.735s = 1.908s".E2E Verification
cargo test --workspace --features cli)packages/python/e2e-attestations/<branch>.jsonreceipt written ifpackages/pythonchanged (just e2e-attest-python)packages/ts/e2e-attestations/<branch>.jsonreceipt written ifpackages/tschanged (just e2e-attest-ts)cargo test --workspace --features cli,just e2e-attest-python,just e2e-attest-tsdirsql queryon the 2048-file fixture gives the same per-role counts as the native pipeline (assistant 68268, user 68267).Changelog / Migrations
<root>/<pkg>/changelog.d/for each changed package (or:skip-changelogtrailer on a commit with reason)<root>/<pkg>/migrations.d/for each changed package (every subsection but Summary_None._when nothing breaks)