Scanned 1509 C# files in OpenRA (C# RTS game engine, Command & Conquer style). MOAD-0001 (CWE-407): CLEAN. Exceptionally well-optimized. FrozenSet<string> for config type checks, HashSet<Actor/CPos> for membership, binary search in TraitDictionary, CellLayer bounds checks. Only List.Contains on small bounded collections (<50 items). MOAD-0002 (Intertangle): CLEAN. Trait-based ECS architecture. No god objects. MOAD-0003 (Leaked Context): CLEAN. Single ThreadLocal for diagnostics only. MOAD-0004 (CWE-312): CLEAN. Only public identifiers logged, no secrets. MOAD-0005 (Thundering Herd): CLEAN. Single-threaded game logic, proper lock() on multi-threaded subsystems.
28 lines
1.1 KiB
Diff
28 lines
1.1 KiB
Diff
# Widelands CWE-407: find_reachable_immovables_unique std::find on vector O(N²)
|
|
# File: src/logic/map.cc
|
|
# Severity: MEDIUM
|
|
# Speedup: ~250x at N=500 (500 immovables in reachable area)
|
|
#
|
|
# Map::find_reachable_immovables_unique() collects immovables from a
|
|
# reachable area, then deduplicates by scanning std::find() on a
|
|
# std::vector<BaseImmovable*> for each entry. This is O(N²) where
|
|
# N = number of immovables found. Called from soldier combat and
|
|
# player territory operations.
|
|
#
|
|
# Fix: Use std::unordered_set<BaseImmovable*> for O(1) dedup lookups.
|
|
--- a/src/logic/map.cc
|
|
+++ b/src/logic/map.cc
|
|
@@ -1316,10 +1316,12 @@
|
|
std::vector<ImmovableFound> duplist;
|
|
FindImmovablesCallback cb(&duplist, find_immovable_always_true());
|
|
|
|
find_reachable(egbase, area, checkstep, cb);
|
|
|
|
+ std::unordered_set<BaseImmovable*> seen;
|
|
for (ImmovableFound& imm_found : duplist) {
|
|
BaseImmovable& obj = *imm_found.object;
|
|
- if (std::find(list.begin(), list.end(), &obj) == list.end()) {
|
|
+ if (seen.insert(&obj).second) {
|
|
if (functor.accept(obj)) {
|
|
list.push_back(&obj);
|
|
}
|