Skip to content

perf(spectrum): build the backward RC query in a stack buffer - #33

Merged
nh13 merged 1 commit into
mainfrom
feat/v0.3-bwd-stackbuf
Jun 13, 2026
Merged

perf(spectrum): build the backward RC query in a stack buffer#33
nh13 merged 1 commit into
mainfrom
feat/v0.3-bwd-stackbuf

Conversation

@nh13

@nh13 nh13 commented Jun 13, 2026

Copy link
Copy Markdown

v0.3 perf series — PR-C (C-alloc), part 1 of the net-new alloc trims (the forward-routing commits are subsumed by #23's O(log) rewrite; see triage below).

What

mem_search_backward built a fresh Vec<u8> for the reverse-complement query on every call — and the consumer fires ~50 backward calls per read. This builds it into a 256-byte stack buffer for the common read length, falling back to the heap only for reads longer than the buffer.

Byte-identical

Same (b & 0x3) ^ 0x3 bytes, same q_key, same forward_maximal_len input — output unchanged. Guarded by the existing mem_search_backward_equals_maximal_backward_step oracle proptest (passes unchanged). Pure hot-path alloc removal.

Why it's clean

This is the exact rc_stack/rc_heap pattern already merged in mem_search_backward_truncated_span_rc (#27) and _interval_rc (#30) — mem_search_backward was the one RC-build path that still allocated. So it's also a sibling-consistency fix: the three RC-build sites now match.

PR-C triage (recorded for the series)

The carving plan flagged PR-C (forward micro-opts) as needing a triage vs merged #23. Result:

Pre-PR /coderabbitai-review: 0 findings.

Summary by CodeRabbit

  • Refactor
    • Optimized memory allocation strategy in search operations to reduce heap allocations and improve performance for common query sizes.

`mem_search_backward` allocated a fresh `Vec` for the reverse-complement query
on every call (the consumer fires ~50 backward calls/read). Build it into a
256-byte stack buffer for the common read length instead, falling back to the
heap only for reads longer than the buffer (e.g. long-read tech).

No probe/result change — byte-identical (the `mem_search_backward_equals_maximal_backward_step`
oracle proptest passes unchanged) — just removes the per-call heap allocation
from the hot backward path. This is the exact `rc_stack`/`rc_heap` pattern already
merged in `mem_search_backward_truncated_span_rc`/`_interval_rc` (#27/#30),
applied to `mem_search_backward`'s RC build.
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 873121c1-7f35-433e-95e3-524f9f483fac

📥 Commits

Reviewing files that changed from the base of the PR and between b658018 and 5d61f2f.

📒 Files selected for processing (1)
  • prmi/src/index/spectrum.rs

📝 Walkthrough

Walkthrough

In LearnedIndex::mem_search_backward, the reverse-complement construction for ambiguous anchors switches from always allocating a heap Vec<u8> to a stack-first approach. A fixed 256-byte stack buffer handles common read lengths; only longer sequences trigger heap allocation. The mask-and-complement transformation (b & 0x3) ^ 0x3 maintains the 2-bit representation.

Changes

Reverse-complement memory allocation

Layer / File(s) Summary
Stack buffer with conditional heap fallback for reverse-complement
prmi/src/index/spectrum.rs
Reverse-complement construction uses a 256-byte stack buffer for common read lengths; mask-and-complement transformation (b & 0x3) ^ 0x3 preserves 2-bit encoding while avoiding underflow; the resulting slice is passed to forward_maximal_len to compute match length.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • fg-labs/prmi#23: Both PRs modify reverse-complement query construction in mem_search_backward's ambiguous-anchor path, with different approaches to optimization.
  • fg-labs/prmi#17: Both PRs modify the backward spectrum search implementation in mem_search_backward with changes to reverse-complement handling.

Poem

🐰 A buffer on the stack so fleet,
No heap allocation, oh what a treat!
Bits flip and dance in masks of grace,
Memory saved in every race. 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: optimizing RC query construction in mem_search_backward by using a stack buffer instead of heap allocation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nh13
nh13 merged commit 7f190f3 into main Jun 13, 2026
4 checks passed
@nh13
nh13 deleted the feat/v0.3-bwd-stackbuf branch June 13, 2026 16:40
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