Skip to content

Vec::drain with VecDeque::pop_front for O(1) log pruning across all apps#42

Open
AdityaShome wants to merge 1 commit intomofa-org:mainfrom
AdityaShome:log-pruning-cpu-spikes
Open

Vec::drain with VecDeque::pop_front for O(1) log pruning across all apps#42
AdityaShome wants to merge 1 commit intomofa-org:mainfrom
AdityaShome:log-pruning-cpu-spikes

Conversation

@AdityaShome
Copy link
Copy Markdown

Problem:

All three apps (mofa-fm, mofa-debate, mofa-asr) stored log entries in a Vec<String> capped at 5,000 entries. When full, Vec::drain(0..excess) removed the oldest shifting all remaining elements left in O(n) time. During active voice chat (logs arriving every 50ms), this caused periodic CPU spikes on the UI thread.

Additionally, mofa-debate had no pruning at all, allowing unbounded memory growth during long sessions.
Fixes: #40

Solution:

Switched from Vec<String> to VecDeque<String> with push_back() / pop_front() — O(1) per eviction. Same ring-buffer pattern already used in mofa-metrics/src/store.rs.

Changes:

File Change
mod.rs (mofa-fm) Vec<String>VecDeque<String>
log_panel.rs (mofa-fm) pushpush_back, drainpop_front + unit tests
audio_controls.rs (mofa-fm) vec![...]VecDeque::from(vec![...])
mod.rs (mofa-debate) Vec<String>VecDeque<String>
log_panel.rs (mofa-debate) Same + added missing MAX_LOG_ENTRIES cap
audio_controls.rs (mofa-debate) vec![...]VecDeque::from(vec![...])
mod.rs (mofa-asr) Vec<String>VecDeque<String>
log_panel.rs (mofa-asr) pushpush_back, drainpop_front

Benchmark: (200K inserts, release mode)

Approach Time
Vec + drain(0..excess) 322ms
VecDeque + pop_front() 7.4ms
Speedup 44x

Testing:

  • cargo check --workspace passes, no new warnings
  • cargo test -p mofa-fm -- log_panel::tests 6/6 pass
  • Tests cover: capacity limits, FIFO ordering, boundary conditions, batch inserts, clear

@Sourya07
Copy link
Copy Markdown

@AdityaShome issue #23
please take a look

@AdityaShome
Copy link
Copy Markdown
Author

AdityaShome commented Feb 25, 2026

Hello, my PR #42 is different from #23 as #23 is about DirtyVec::push in mofa-dora-bridge/src/shared_state.rs.
My changes are in the app display layer: apps/mofa-fm/, apps/mofa-debate/, and apps/mofa-asr/, same class of O(n) bug with no overlap.
I also added a missing MAX_LOG_ENTRIES cap in mofa-debate that didn't exist anywhere and fixes how each app's log panel prunes its own display buffer. These two issues are independent and both need to be fixed.

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.

Vec_drain causes O(n) CPU spikes in log panel pruning

2 participants