Skip to content

[improve](hgraph): reuse idle visited lists across sub-pools before allocating #2427

Description

@jac0626

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

Metadata

Metadata

Assignees

Labels

kind/improvementOptimizations, UX polish, or minor improvements 性能优化、体验打磨或细节改良needs-triageNeeds kind and version triage

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions