Skip to content

refactor: improve time complexity and reduce memory allocations#5601

Open
chabinhwang wants to merge 1 commit intospring-projects:mainfrom
chabinhwang:refactor/improve-time-complexity
Open

refactor: improve time complexity and reduce memory allocations#5601
chabinhwang wants to merge 1 commit intospring-projects:mainfrom
chabinhwang:refactor/improve-time-complexity

Conversation

@chabinhwang
Copy link
Copy Markdown
Contributor

@chabinhwang chabinhwang commented Mar 15, 2026

Summary

  • DefaultToolCallingManager: Pre-compute HashSet of existing tool names to reduce resolveToolDefinitions lookup from O(N×M) to O(N+M)
  • ModelOptionsUtils: Change interfaceNames from List to Set for O(1) contains() instead of O(N), use Character.toUpperCase() to avoid unnecessary String allocation in toGetName()
  • Vector stores (16 files): Replace documents.indexOf(document) O(N) lookup inside loops with index-based access O(1), eliminating O(N²) overall complexity in doAdd methods

Details

DefaultToolCallingManager (resolveToolDefinitions)

Previously, for each tool name in chatOptions.getToolNames(), the code streamed through all toolCallbacks with .anyMatch() — resulting in O(N×M) complexity. Now a HashSet<String> of existing tool callback names is pre-computed once, reducing the check to O(1) per iteration.

ModelOptionsUtils (mergeBeans / toGetName)

  • interfaceNames was collected as a List<String> but used with .contains() which is O(N) per call. Changed to Set<String> for O(1) lookups.
  • toGetName() used name.substring(0, 1).toUpperCase() which creates an intermediate String object. Changed to Character.toUpperCase(name.charAt(0)) to avoid unnecessary allocation.

Vector Stores (16 files)

All vector store doAdd methods used documents.indexOf(document) inside a for-each loop to correlate documents with their embeddings. Since indexOf is O(N), this made the overall loop O(N²). Replaced with indexed for-loops using embeddings.get(i) for O(1) access.

Affected stores: Cassandra, Chroma, Couchbase, GemFire, MariaDB, Milvus, MongoDB Atlas, Neo4j, OpenSearch, Oracle, Pinecone, Qdrant, Redis, Typesense, Azure, CosmosDB

- DefaultToolCallingManager: pre-compute HashSet of existing tool names
  to reduce resolveToolDefinitions lookup from O(N*M) to O(N+M)
- ModelOptionsUtils: change interfaceNames from List to Set for O(1)
  contains() instead of O(N), use Character.toUpperCase() to avoid
  unnecessary String allocation in toGetName()
- Vector stores (16 files): replace documents.indexOf(document) O(N)
  lookup inside loops with index-based access O(1), eliminating O(N^2)
  overall complexity in doAdd methods

Signed-off-by: chabinhwang <7chabin@gmail.com>
@ericbottard ericbottard self-requested a review March 16, 2026 08:49
@ericbottard ericbottard added this to the 2.0.0-M4 milestone Mar 16, 2026
@sdeleuze sdeleuze modified the milestones: 2.0.0-M4, 2.0.0-M5 Mar 25, 2026
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.

3 participants