From e313ef443ab8566e04b17f5f0befbd87eb81dc28 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 14 Aug 2024 09:44:43 -0400 Subject: [PATCH 1/2] fix: performance issue with InMemoryBackingStore Signed-off-by: Vincent Biret --- CHANGELOG.md | 6 ++++++ Directory.Build.props | 2 +- src/abstractions/store/InMemoryBackingStore.cs | 13 ++++++------- .../abstractions/Store/InMemoryBackingStoreTests.cs | 7 +++++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a762e13..60c1bdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.11.2] - 2024-08-14 + +### Changed + +- Fixed an additional performance regression with the backing store introduced in version 1.9.2 by #243 + ## [1.11.1] - 2024-08-12 ### Changed diff --git a/Directory.Build.props b/Directory.Build.props index 60173a4..02dccb1 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 1.11.1 + 1.11.2 false diff --git a/src/abstractions/store/InMemoryBackingStore.cs b/src/abstractions/store/InMemoryBackingStore.cs index 8cf7955..4d50c28 100644 --- a/src/abstractions/store/InMemoryBackingStore.cs +++ b/src/abstractions/store/InMemoryBackingStore.cs @@ -81,14 +81,13 @@ public void Set(string key, T? value) // All the list items are dirty as the model has been touched. foreach(var item in collectionValues) { - if(item is IBackedModel model) + // we don't support heterogeneous collections, so we can break if the first item is not a IBackedModel + if(item is not IBackedModel model) break; + model.BackingStore.InitializationCompleted = false; + model.BackingStore.Subscribe((keyString, oldObject, newObject) => { - model.BackingStore.InitializationCompleted = false; - model.BackingStore.Subscribe((keyString, oldObject, newObject) => - { - Set(key, value); - }, key); // use property name(key) as subscriptionId to prevent excess subscription creation in the event this is called again - } + Set(key, value); + }, key); // use property name(key) as subscriptionId to prevent excess subscription creation in the event this is called again } } diff --git a/tests/abstractions/Store/InMemoryBackingStoreTests.cs b/tests/abstractions/Store/InMemoryBackingStoreTests.cs index 599b30f..8760931 100644 --- a/tests/abstractions/Store/InMemoryBackingStoreTests.cs +++ b/tests/abstractions/Store/InMemoryBackingStoreTests.cs @@ -467,7 +467,7 @@ public void TestsBackingStoreNestedInvocationCounts() Assert.Equal(2, invocationCount);// only called twice } - private readonly int[] _testArray = Enumerable.Range(0, 100000000).ToArray(); + private readonly int[] _testArray = Enumerable.Range(0, 1000000000).ToArray(); [Fact] public void TestsLargeArrayPerformsWell() { @@ -475,8 +475,11 @@ public void TestsLargeArrayPerformsWell() var testBackingStore = new InMemoryBackingStore(); // Act Assert.Empty(testBackingStore.Enumerate()); - testBackingStore.Set("email", _testArray); var stopWatch = Stopwatch.StartNew(); + testBackingStore.Set("email", _testArray); + stopWatch.Stop(); + Assert.InRange(stopWatch.ElapsedMilliseconds, 0, 2); + stopWatch.Restart(); testBackingStore.InitializationCompleted = true; stopWatch.Stop(); // Assert From b5f363572b0c34f6261b84429f474b0e9d6bd966 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 14 Aug 2024 09:57:17 -0400 Subject: [PATCH 2/2] fix: reverts array size due to framework memory alloc Signed-off-by: Vincent Biret --- tests/abstractions/Store/InMemoryBackingStoreTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/abstractions/Store/InMemoryBackingStoreTests.cs b/tests/abstractions/Store/InMemoryBackingStoreTests.cs index 8760931..1d00a82 100644 --- a/tests/abstractions/Store/InMemoryBackingStoreTests.cs +++ b/tests/abstractions/Store/InMemoryBackingStoreTests.cs @@ -467,7 +467,7 @@ public void TestsBackingStoreNestedInvocationCounts() Assert.Equal(2, invocationCount);// only called twice } - private readonly int[] _testArray = Enumerable.Range(0, 1000000000).ToArray(); + private readonly int[] _testArray = Enumerable.Range(0, 100000000).ToArray(); [Fact] public void TestsLargeArrayPerformsWell() { @@ -478,12 +478,12 @@ public void TestsLargeArrayPerformsWell() var stopWatch = Stopwatch.StartNew(); testBackingStore.Set("email", _testArray); stopWatch.Stop(); - Assert.InRange(stopWatch.ElapsedMilliseconds, 0, 2); + Assert.InRange(stopWatch.ElapsedMilliseconds, 0, 1); stopWatch.Restart(); testBackingStore.InitializationCompleted = true; stopWatch.Stop(); // Assert - Assert.InRange(stopWatch.ElapsedMilliseconds, 0, 2); + Assert.InRange(stopWatch.ElapsedMilliseconds, 0, 1); } ///