Fix O(n^2) performance bottleneck in CClientStreamer #4695
+57
−69
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Replace O(n) linear scans in CClientStreamer with O(1) hash-based lookups to eliminate quadratic performance degradation during bulk element creation.
Changes
AddToSortedList: Replace ListContains O(n) duplicate check with Count O(1), and remove redundant sort insertion (DoPulse already sorts every frame)
IsActiveElement: O(n) list scan -> O(1) set lookup
FindOrCreateRow/FindRow: Replace linear m_ExtraRows list search with unordered_map for O(1) row lookups
AddElements/RemoveElements: Accept optional unordered_set for O(1) duplicate checks during sector activation/deactivation
Motivation
Creating many elements in a loop especially via createObject() while the player/camera is at high altitudes -> z > 25000 caused severe performance issues, sometimes up to >35 seconds of load time depending on the camera position and this would increase drastically the higher up you would go.
As each new element passes through AddToSortedList which scanned the entire m_ActiveElements list for both duplicate checking and sorted insertion. With n elements, this results in 1+2+3+...+n = O(n^2) total work ~50 million operations for 10k elements.
The sorted insertion seems to be redundant since DoPulse already calls m_ActiveElements.sort(CompareExpDistance) every frame before ReStream consumes the list
Test plan
Load times can vary heavily dependant on system specs and camera position like already mentioned before
Checklist