Measure what the commands cost, and save a baseline - #126
Merged
Merged
Conversation
Thirty-eight commands and not one number attached to any of them. criterion benchmarks below the command boundary, against a file-backed database of 800 notes of ~13 kB — the shape already quoted in notes/view.rs. The first baseline is in docs/architecture.md. Two things it says: query_notes costs 27 ms on 800 notes and runs on every keystroke, and the search is not what costs — filtering is cheaper than not filtering, so the accent fold is not the dominant term. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TLS 1.3 handshake messages were accepted across encryption level boundaries. The handshake transcript stays authenticated, so a network-position attacker cannot alter or complete one — the effect is that a peer could send in plaintext what should have been encrypted without the connection being rejected. Reached through tauri-plugin-updater, which is the only thing here that speaks TLS. Both packages named on one command: 0.23.45 wants webpki ^0.103.14 and the lockfile held 0.103.13, so updating rustls alone falls back to 0.23.43 — which is still below the fix — rather than move a sibling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
query_notes costs 403 ms there, past its own 150 ms debounce, and list_tags is the only command that degrades faster than the corpus. Corpus dropped its temp directory while SQLite still held the file open, which Windows refuses to delete over: six groups leaked a corpus each. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
licenses, bans and sources never made a decision in 25 runs. Advisories stay: Dependabot alerts are off, so this is the only net there is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Closes #78.
A criterion harness under the command boundary, a baseline to compare against, and the three
things that came out of taking it seriously.
What is measured
store::*+view::*+ the serde round-trip — a command is four lines, so that is nearly allof its cost. Six groups against a file-backed database of 8000 notes of ~13 kB (~104 MB,
seeded once per group); an in-memory one has no pager, no page cache and no I/O, and would
measure something the application never does.
Not in CI, and not in
cargo testeither — cargo gives a[[bench]]targettest = false,so the suite never builds it. A timing assertion on a shared runner flaps.
query_notes, search matching nothingquery_notes, unfilteredquery_notes, search folding accentsexport_notes/import_noteslist_tagsdelete_notesthenrestore_notes, 100 notesrename_tagacross the corpusmove_notes/tag_notes, 100 noteslist_trashupdate_notelist_global_placeholdersquery_noteshas gone past its own debounce. It runs on every keystroke behind 150 ms; at800 notes its 27 ms sat comfortably inside, at 8000 the query fired for one keystroke is still
running when the third one after it arrives. That is what #21 is about, and it has stopped being
theoretical.
The search still is not what costs. Folding accents is the cheapest of the three variants
— fewer notes survive to be serialised. Fetching 8000 × 13 kB out of SQLite and turning the view
into JSON is the whole cost.
list_tagsdegrades faster than the corpus. ×64 for ×10 the data, the only entry that does,and invisible at 800 notes where it cost 591 µs. It joins
note_tagstonotesto read onenullable column, so each of the 16 000 tag rows dereferences a ~13 kB note row.
not confirmed — no query plan was taken.
--save-baseline mainwrites lands in the gitignoredtarget/: local to onemachine, gone with
cargo clean. The table indocs/architecture.mdis the durable record.The corpus leaked, every run
impl Drop for Corpuserased the temp directory — butDrop::dropruns before the struct'sfields, so SQLite still held the file open, and Windows refuses to delete over an open handle.
let _ =swallowed the error. Measured: 18 directories, 709 MB in%TEMP%, six added perrun, and at 8000 notes each one is ~104 MB.
The erasure moved onto a
TempDirfield declared last — fields drop in declaration order, sothe connection closes first. Verified on a 50-note corpus: six built and torn down, zero left.
Two pieces of housekeeping
Cargo.tomlwent from 128 lines to 94 with no comments left. What was load-bearing there(
autobenches = false,bench = false, and nowCorpusnot implementingDrop) is indocs/architecture.md.cargo-denyis down tocheck advisories, anddeny.tomlfrom 65 lines to 14. Across thelast 25
security.ymlruns,licenses,bansandsourcesnever made a single decision; theone time the job went red it was this branch's rustls advisory. Advisories stay because
repos/…/dependabot/alertsanswers "Dependabot alerts are disabled for this repository" — itis the only net there is. GPL-3.0 compatibility becomes a release-time review rather than a
per-pull-request gate.
Also on this branch
rustlspast RUSTSEC-2026-0285 (0.23.43 → 0.23.45), which is what turned the Security jobred in the first place.
cargo update -p rustlsalone stopsat 0.23.43. 0.23.45 requires
webpki ^0.103.14and the lockfile held 0.103.13; a single-packageupdate is conservative and will not move a sibling to satisfy the package it was asked about, so
it falls back to the newest version compatible with what is already locked.
Lockfile only. No
--precisepin and no MSRV change — every crate involved declaresrust-version = "1.71", sorust-version = "1.88"was never the gate, and raising it as far as1.93 changes nothing. Cargo's "latest Rust 1.88 compatible version" line describes its resolution
mode, not a refusal.
Checks
cargo fmt --check,cargo clippy --all-targets --all-features -- -D warnings,cargo test(321 tests) — all green locally.
🤖 Generated with Claude Code