From b2fdde346cb461751955233ce043d4efdf977832 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:37:30 +0000 Subject: [PATCH] Optimize SynchronizedCollection.Get to cache the snapshot and eliminate allocations on every call Co-authored-by: johnstrand <11484777+johnstrand@users.noreply.github.com> --- .../Types/Collections/SynchronizedCollection.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/GameUtils/Types/Collections/SynchronizedCollection.cs b/src/GameUtils/Types/Collections/SynchronizedCollection.cs index 5d29626..901c76c 100644 --- a/src/GameUtils/Types/Collections/SynchronizedCollection.cs +++ b/src/GameUtils/Types/Collections/SynchronizedCollection.cs @@ -31,6 +31,8 @@ public abstract class SynchronizedCollection : IEnumerable where T : notnu { private readonly ConcurrentQueue> _pending = new(); private readonly SemaphoreSlim _integrating = new(1, 1); + private IReadOnlyList? _cachedSnapshot; + private bool _dirty = true; /// /// Schedules an entity to be added to the collection. @@ -57,9 +59,16 @@ public void Integrate() _integrating.Wait(); try { + bool modified = false; while (_pending.TryDequeue(out var operation)) { HandleOperation(operation); + modified = true; + } + + if (modified) + { + _dirty = true; } } finally @@ -101,7 +110,13 @@ public IEnumerable Get() _integrating.Wait(); try { - return GetInternal().ToList(); + if (_dirty || _cachedSnapshot is null) + { + _cachedSnapshot = GetInternal().ToList(); + _dirty = false; + } + + return _cachedSnapshot; } finally {