You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ AI-generated issue — requires human investigation before acting on it.
Summary
HashCounter::iter in src/collector.rs builds a deeply-nested Box<dyn Iterator> chain by wrapping each of the 4096 buckets in a new Box::new(iter.chain(...)). This allocates 4096 heap objects every time a report is built.
Location
src/collector.rs, lines 137–145:
pubfniter(&self) -> implIterator<Item = &Entry<T>>{letmut iter:Box<dynIterator<Item = &Entry<T>>> =
Box::new(self.buckets[0].iter().chain(std::iter::empty()));for bucket inself.buckets[1..].iter(){
iter = Box::new(iter.chain(bucket.iter()));// ← 4095 allocations}
iter
}
Impact
4096 heap allocations per call to try_iter / report build.
Each next() call on the resulting iterator traverses a chain of 4096 dynamic dispatch steps before reaching a real element.
O(N²) behaviour in the worst case when iterating through all entries.
Summary
HashCounter::iterinsrc/collector.rsbuilds a deeply-nestedBox<dyn Iterator>chain by wrapping each of the 4096 buckets in a newBox::new(iter.chain(...)). This allocates 4096 heap objects every time a report is built.Location
src/collector.rs, lines 137–145:Impact
try_iter/ report build.next()call on the resulting iterator traverses a chain of 4096 dynamic dispatch steps before reaching a real element.Expected behaviour
Replace with a flat iterator:
This requires zero extra allocations and has O(1) dispatch overhead per element.