refactor: drop Transcript::read_seq, a public field nothing reads - #170
Open
BenjaminDEMAILLE wants to merge 2 commits into
Open
refactor: drop Transcript::read_seq, a public field nothing reads#170BenjaminDEMAILLE wants to merge 2 commits into
BenjaminDEMAILLE wants to merge 2 commits into
Conversation
The field was filled with a full copy of the read at every finalised transcript and assigned again in four more places, and no code in the crate reads it. Not "reads it rarely": the compiler was asked, and after deleting the field every one of the 97 resulting errors is a struct literal or an assignment. There is no read site, in `src` or in tests. Measured on 200k real reads at 8 threads: about 50 transcripts are finalised per read, so removing it takes **15.1 million allocations off a 200 million total** (7.6%) and 3.87 GB of copying. Wall clock does not move, and that is worth recording rather than hiding: six interleaved rounds at 87-92% CPU idle give medians 20.90 s against 20.65 s with the direction mixed, inside the run-to-run spread. mimalloc is fast enough that seventy-five small allocations per read do not surface. The reason to remove it is that it is dead weight, not that it is slow. That number also calibrates scverse#168 downward: if removing 7.6% of the allocations changes nothing measurable, the rest of the allocation programme is unlikely to be worth a new dependency. `Transcript::read_seq` is `pub`, so this is an API removal and needs sign-off. Nothing outside the crate can be relying on its contents being meaningful, though, since it is only ever written. Output-neutral: SAM byte-identical on 200k real reads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 30, 2026
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.
Transcript::read_seqis filled with a full copy of the read at every finalised alignment, and nothing in the crate reads it.How I know nothing reads it
Not from grepping. I deleted the field and asked the compiler. All 97 resulting errors are struct literals or assignments:
Not one read site, in
srcor in tests. The three places that looked like readers on a grep are something else:io/sam.rs:265uses a local parameter of the same name, andchimeric/output.rs:148,157readChimericAlignment::read_seq, a different struct filled from its own parameter inchimeric/detect.rs.What it costs
Measured on 200 000 real reads (
ERR12389696, yeast) at 8 threads, with the global allocator wrapped in a counter:15.1 million allocations removed, 7.6% of the total, and 3.87 GB of copying. About 50 transcripts are finalised per read, each copying the whole read.
Wall clock: no change, and that is the interesting part
Six interleaved rounds, 2M reads,
--runThreadN 16, 87-92% CPU idle:Direction mixed, inside the run-to-run spread. One round had a clear outlier which I have not excluded from the medians.
So removing 7.6% of all allocations moves nothing measurable. mimalloc is fast, and it is already tuned in
src/main.rs. That calibrates #168 downward: I estimated an ~11% ceiling for allocation work from the profile's mimalloc share, and this says that estimate is too generous. I would not spend a new dependency on the rest of it without a workload that shows the cost, and I have updated #168 accordingly.The reason to take this change is that the field is dead weight, which
CONTRIBUTING.mdrules out on its own terms. The allocations are a bonus, not the argument.One thing needing your call
Transcript::read_seqispub, so this is an API removal. Nothing outside the crate can be relying on its contents, since it is only ever written, but the field disappearing is still a breaking change for anyone naming it. Say the word if you would rather keep it as a deprecated always-empty field for a release.Verification
Output-neutral: SAM byte-identical on 200 000 real reads against
origin/main, whole file including header.Gate: 560 lib + 26 integration tests,
cargo clippy --all-targets -- -D warnings,cargo fmt --check, all green.