From 309b1276af9fc933579beda50a585b38e4c1bda5 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 21 Jul 2022 10:12:31 +0200 Subject: [PATCH] WIP: Tweaking benchmarks. --- .../Base/ValueStoreAddRemoveBenchmarks.cs | 207 ++++++++++++++++-- 1 file changed, 184 insertions(+), 23 deletions(-) diff --git a/tests/Avalonia.Benchmarks/Base/ValueStoreAddRemoveBenchmarks.cs b/tests/Avalonia.Benchmarks/Base/ValueStoreAddRemoveBenchmarks.cs index 9397ea79b4..9ac4a91f1b 100644 --- a/tests/Avalonia.Benchmarks/Base/ValueStoreAddRemoveBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Base/ValueStoreAddRemoveBenchmarks.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Avalonia.Utilities; using BenchmarkDotNet.Attributes; @@ -210,7 +211,7 @@ internal static class MockProperties } [MemoryDiagnoser] -public class ValueStoreLookupBenchmarks +public class ValueStore_Lookup { [Params(2, 6, 10, 20, 30)] public int PropertyCount; @@ -222,17 +223,20 @@ public class ValueStoreLookupBenchmarks private AvaloniaPropertyValueStore _store; private AvaloniaPropertyValueStoreOld _oldStore; + private Dictionary _dictionary; [GlobalSetup] public void GlobalSetup() { _store = new AvaloniaPropertyValueStore(); _oldStore = new AvaloniaPropertyValueStoreOld(); + _dictionary = new Dictionary(); for (int i = 0; i < PropertyCount; i++) { _store.AddValue(Properties[i], null); _oldStore.AddValue(Properties[i], null); + _dictionary.Add(Properties[i], null); } } @@ -245,17 +249,26 @@ public class ValueStoreLookupBenchmarks } } - [Benchmark] public void LookupProperties_Old() + [Benchmark(Baseline = true)] public void LookupProperties_Old() { for (int i = 0; i < PropertyCount; i++) { _oldStore.TryGetValue(Properties[i], out _); } } + + [Benchmark] + public void LookupProperties_Dict() + { + for (int i = 0; i < PropertyCount; i++) + { + _dictionary.TryGetValue(Properties[i], out _); + } + } } [MemoryDiagnoser] -public class ValueStoreAddRemoveBenchmarks +public class ValueStore_AddBenchmarks { [Params(2, 6, 10, 20, 30)] public int PropertyCount; @@ -264,11 +277,11 @@ public class ValueStoreAddRemoveBenchmarks public bool UseShuffledProperties; public AvaloniaProperty[] Properties => UseShuffledProperties ? MockProperties.ShuffledProperties : MockProperties.LinearProperties; - + [Benchmark] [Arguments(false)] [Arguments(true)] - public void AddValue(bool isInitializing) + public void Add(bool isInitializing) { var store = new AvaloniaPropertyValueStore { IsInitializing = isInitializing }; @@ -277,7 +290,42 @@ public class ValueStoreAddRemoveBenchmarks store.AddValue(Properties[i], null); } } - + + [Benchmark(Baseline = true)] + public void Add_Old() + { + var store = new AvaloniaPropertyValueStoreOld(); + + for (int i = 0; i < PropertyCount; i++) + { + store.AddValue(Properties[i], null); + } + } + + [Benchmark] + public void Add_Dict() + { + var store = new Dictionary(); + + for (int i = 0; i < PropertyCount; i++) + { + store.Add(Properties[i], null); + } + } +} + + +[MemoryDiagnoser] +public class ValueStore_AddRemoveBenchmarks +{ + [Params(2, 6, 10, 20, 30)] + public int PropertyCount; + + [Params(false, true)] + public bool UseShuffledProperties; + + public AvaloniaProperty[] Properties => UseShuffledProperties ? MockProperties.ShuffledProperties : MockProperties.LinearProperties; + [Benchmark] [Arguments(false)] [Arguments(true)] @@ -289,13 +337,57 @@ public class ValueStoreAddRemoveBenchmarks { store.AddValue(Properties[i], null); } - + for (int i = PropertyCount - 1; i >= 0; i--) { store.Remove(Properties[i]); } } - + + [Benchmark(Baseline = true)] + public void AddAndRemoveValue_Old() + { + var store = new AvaloniaPropertyValueStoreOld(); + + for (int i = 0; i < PropertyCount; i++) + { + store.AddValue(Properties[i], null); + } + + for (int i = PropertyCount - 1; i >= 0; i--) + { + store.Remove(Properties[i]); + } + } + + [Benchmark] + public void AddAndRemoveValue_Dict() + { + var store = new Dictionary(); + + for (int i = 0; i < PropertyCount; i++) + { + store.Add(Properties[i], null); + } + + for (int i = PropertyCount - 1; i >= 0; i--) + { + store.Remove(Properties[i]); + } + } +} + +[MemoryDiagnoser] +public class ValueStore_AddRemoveInterleavedBenchmarks +{ + [Params(2, 6, 10, 20, 30)] + public int PropertyCount; + + [Params(false, true)] + public bool UseShuffledProperties; + + public AvaloniaProperty[] Properties => UseShuffledProperties ? MockProperties.ShuffledProperties : MockProperties.LinearProperties; + [Benchmark] [Arguments(false)] [Arguments(true)] @@ -310,42 +402,111 @@ public class ValueStoreAddRemoveBenchmarks } } - [Benchmark] - public void AddValue_Old() + [Benchmark(Baseline = true)] + public void AddAndRemoveValueInterleaved_Old() { var store = new AvaloniaPropertyValueStoreOld(); for (int i = 0; i < PropertyCount; i++) { store.AddValue(Properties[i], null); + store.Remove(Properties[i]); } } - + [Benchmark] - public void AddAndRemoveValue_Old() + public void AddAndRemoveValueInterleaved_Dict() { - var store = new AvaloniaPropertyValueStoreOld(); + var store = new Dictionary(); for (int i = 0; i < PropertyCount; i++) { - store.AddValue(Properties[i], null); + store.Add(Properties[i], null); + store.Remove(Properties[i]); } - - for (int i = PropertyCount - 1; i >= 0; i--) + } +} + + +[MemoryDiagnoser] +public class ValueStore_Enumeration +{ + [Params(2, 6, 10, 20, 30)] + public int PropertyCount; + + [Params(false, true)] + public bool UseShuffledProperties; + + public AvaloniaProperty[] Properties => UseShuffledProperties ? MockProperties.ShuffledProperties : MockProperties.LinearProperties; + + private AvaloniaPropertyValueStore _store; + private AvaloniaPropertyValueStoreOld _oldStore; + private Dictionary _dictionary; + + [GlobalSetup] + public void GlobalSetup() + { + _store = new AvaloniaPropertyValueStore(); + _oldStore = new AvaloniaPropertyValueStoreOld(); + _dictionary = new Dictionary(); + + for (int i = 0; i < PropertyCount; i++) { - store.Remove(Properties[i]); + _store.AddValue(Properties[i], null); + _oldStore.AddValue(Properties[i], null); + _dictionary.Add(Properties[i], null); } } - + [Benchmark] - public void AddAndRemoveValueInterleaved_Old() + public int Enumerate() { - var store = new AvaloniaPropertyValueStoreOld(); + var result = 0; - for (int i = 0; i < PropertyCount; i++) + for (int i = 0; i < _store.Count; i++) { - store.AddValue(Properties[i], null); - store.Remove(Properties[i]); + result += _store[i] is null ? 1 : 0; + } + + return result; + } + + [Benchmark(Baseline = true)] + public int Enumerate_Old() + { + var result = 0; + + for (int i = 0; i < _store.Count; i++) + { + result += _oldStore[i] is null ? 1 : 0; + } + + return result; + } + + [Benchmark] + public int Enumerate_Dict() + { + var result = 0; + + foreach (var i in _dictionary) + { + result += i.Value is null ? 1 : 0; } + + return result; + } + + [Benchmark] + public int Enumerate_DictValues() + { + var result = 0; + + foreach (var i in _dictionary.Values) + { + result += i is null ? 1 : 0; + } + + return result; } }