Kind of improvement
perf
Affected area
hgraph
Summary
ResourceObjectPool<VisitedList>::TakeOne() partitions the pool into 16 sub-pools and prefers a thread-local sub-pool. When the chosen sub-pool is empty, it allocates a new VisitedList immediately instead of checking whether other sub-pools already hold idle objects. In HGraph search, each request takes one visited list and returns it after route-graph and bottom-graph search (src/algorithm/hgraph/hgraph_search.cpp:453, src/algorithm/hgraph/hgraph_search.cpp:544), so peak allocation count depends heavily on this pool policy.
For large-capacity indexes, each VisitedList is expensive because it stores one uint16_t tag per inner id (src/utils/visited_list.h:30, src/utils/visited_list.h:54). Under search pressure, the current allocation policy can grow the cached object count more than necessary even when other sub-pools already have idle objects.
Suggested direction: before allocating a new object, try to reuse from another non-empty sub-pool; alternatively maintain a small global overflow free list.
Expected benefit
Reduce the peak number of live VisitedList objects without changing HGraph search semantics. This should lower scratch RSS / allocator live bytes for large-capacity indexes and make memory usage less sensitive to thread scheduling.
Benchmark evidence
Observed in a search stress test with a custom allocator instrumented by backtrace:
- call path:
HGraph::KnnSearch -> HGraph::SearchWithRequest -> ResourceObjectPool<VisitedList>::TakeOne -> VisitedList::VisitedList -> SafeAllocator::Allocate
- the visited-list pool reached
live_count=34 and live_bytes=680026112
- this works out to roughly 20 MB per object, consistent with
VisitedList using uint16_t[max_capacity]
// TODO: add before/after numbers from a patched allocator strategy.
References
- src/utils/resource_object_pool.h:37
- src/utils/resource_object_pool.h:69
- src/utils/visited_list.h:30
- src/utils/visited_list.h:54
- src/algorithm/hgraph/hgraph_search.cpp:453
- src/algorithm/hgraph/hgraph_search.cpp:544
Additional context
This is not a correctness bug by itself; the issue is that the runtime scratch pool keeps more large objects live than necessary.
Related issues
Drafted with AI assistant: Codex:gpt-5
Kind of improvement
perf
Affected area
hgraph
Summary
ResourceObjectPool<VisitedList>::TakeOne()partitions the pool into 16 sub-pools and prefers a thread-local sub-pool. When the chosen sub-pool is empty, it allocates a newVisitedListimmediately instead of checking whether other sub-pools already hold idle objects. In HGraph search, each request takes one visited list and returns it after route-graph and bottom-graph search (src/algorithm/hgraph/hgraph_search.cpp:453,src/algorithm/hgraph/hgraph_search.cpp:544), so peak allocation count depends heavily on this pool policy.For large-capacity indexes, each
VisitedListis expensive because it stores oneuint16_ttag per inner id (src/utils/visited_list.h:30,src/utils/visited_list.h:54). Under search pressure, the current allocation policy can grow the cached object count more than necessary even when other sub-pools already have idle objects.Suggested direction: before allocating a new object, try to reuse from another non-empty sub-pool; alternatively maintain a small global overflow free list.
Expected benefit
Reduce the peak number of live
VisitedListobjects without changing HGraph search semantics. This should lower scratch RSS / allocator live bytes for large-capacity indexes and make memory usage less sensitive to thread scheduling.Benchmark evidence
Observed in a search stress test with a custom allocator instrumented by backtrace:
HGraph::KnnSearch -> HGraph::SearchWithRequest -> ResourceObjectPool<VisitedList>::TakeOne -> VisitedList::VisitedList -> SafeAllocator::Allocatelive_count=34andlive_bytes=680026112VisitedListusinguint16_t[max_capacity]// TODO: add before/after numbers from a patched allocator strategy.References
Additional context
This is not a correctness bug by itself; the issue is that the runtime scratch pool keeps more large objects live than necessary.
Related issues
Drafted with AI assistant: Codex:gpt-5