From 64cce62e7b34f2b843d3258de640858d6bfe94f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Komosi=C5=84ski?= Date: Tue, 12 Apr 2022 23:09:46 +0200 Subject: [PATCH 1/3] Benchmark for finding resources. --- .../Styling/ResourceBenchmarks.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs diff --git a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs new file mode 100644 index 0000000000..1445fcba05 --- /dev/null +++ b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs @@ -0,0 +1,91 @@ +using System; +using Avalonia.Controls; +using Avalonia.Platform; +using Avalonia.PlatformSupport; +using Avalonia.Styling; +using Avalonia.Themes.Fluent; +using Avalonia.UnitTests; +using BenchmarkDotNet.Attributes; +using Moq; + +namespace Avalonia.Benchmarks.Styling +{ + [MemoryDiagnoser] + public class ResourceBenchmarks : IDisposable + { + private readonly Control _searchStart; + private readonly IDisposable _app; + + private static IDisposable CreateApp() + { + var services = new TestServices( + assetLoader: new AssetLoader(), + globalClock: new MockGlobalClock(), + platform: new AppBuilder().RuntimePlatform, + renderInterface: new MockPlatformRenderInterface(), + standardCursorFactory: Mock.Of(), + styler: new Styler(), + theme: () => LoadTheme(), + threadingInterface: new NullThreadingPlatform(), + fontManagerImpl: new MockFontManagerImpl(), + textShaperImpl: new MockTextShaperImpl(), + windowingPlatform: new MockWindowingPlatform()); + + return UnitTestApplication.Start(services); + } + + private static Styles LoadTheme() + { + AssetLoader.RegisterResUriParsers(); + + var hostStyle = new Style(); + + hostStyle.Resources.Add("test", null); + + return new Styles + { + hostStyle, + new FluentTheme(new Uri("avares://Avalonia.Benchmarks")) + }; + } + + public void Dispose() + { + _app.Dispose(); + } + + public ResourceBenchmarks() + { + _searchStart = new Button(); + + _app = CreateApp(); + + Decorator root = new TestRoot(true, null) + { + Renderer = new NullRenderer() + }; + + var current = root; + + for (int i = 0; i < 10; i++) + { + var child = new Decorator(); + + current.Child = child; + + current = child; + } + + current.Child = _searchStart; + } + + [Benchmark(Baseline = true)] + public void FindResource() + { + for (int i = 0; i < 100; ++i) + { + _searchStart.FindResource("test"); + } + } + } +} From 55e681a326673f680f8324fa1bb365be4305f86e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Komosi=C5=84ski?= Date: Tue, 12 Apr 2022 23:15:55 +0200 Subject: [PATCH 2/3] Add more benchmark cases. --- .../Styling/ResourceBenchmarks.cs | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs index 1445fcba05..babfaef6ab 100644 --- a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs @@ -38,14 +38,17 @@ namespace Avalonia.Benchmarks.Styling { AssetLoader.RegisterResUriParsers(); - var hostStyle = new Style(); + var preHost = new Style(); + preHost.Resources.Add("preTheme", null); - hostStyle.Resources.Add("test", null); + var postHost = new Style(); + postHost.Resources.Add("postTheme", null); return new Styles { - hostStyle, - new FluentTheme(new Uri("avares://Avalonia.Benchmarks")) + preHost, + new FluentTheme(new Uri("avares://Avalonia.Benchmarks")), + postHost }; } @@ -79,12 +82,30 @@ namespace Avalonia.Benchmarks.Styling current.Child = _searchStart; } - [Benchmark(Baseline = true)] - public void FindResource() + [Benchmark] + public void FindPreResource() { for (int i = 0; i < 100; ++i) { - _searchStart.FindResource("test"); + _searchStart.FindResource("preTheme"); + } + } + + [Benchmark] + public void FindPostResource() + { + for (int i = 0; i < 100; ++i) + { + _searchStart.FindResource("postTheme"); + } + } + + [Benchmark] + public void FindNotExistingResource() + { + for (int i = 0; i < 100; ++i) + { + _searchStart.FindResource("notPresent"); } } } From a2bcd8a9c95b2fc854939b8ce1ef8f854dfc0e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Komosi=C5=84ski?= Date: Thu, 14 Apr 2022 14:39:56 +0200 Subject: [PATCH 3/3] Remove dependency on fluent theme. --- .../Styling/ResourceBenchmarks.cs | 17 ++++++----- tests/Avalonia.Benchmarks/TestStyles.cs | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 tests/Avalonia.Benchmarks/TestStyles.cs diff --git a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs index babfaef6ab..2a048beefa 100644 --- a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs @@ -3,7 +3,6 @@ using Avalonia.Controls; using Avalonia.Platform; using Avalonia.PlatformSupport; using Avalonia.Styling; -using Avalonia.Themes.Fluent; using Avalonia.UnitTests; using BenchmarkDotNet.Attributes; using Moq; @@ -25,7 +24,7 @@ namespace Avalonia.Benchmarks.Styling renderInterface: new MockPlatformRenderInterface(), standardCursorFactory: Mock.Of(), styler: new Styler(), - theme: () => LoadTheme(), + theme: () => CreateTheme(), threadingInterface: new NullThreadingPlatform(), fontManagerImpl: new MockFontManagerImpl(), textShaperImpl: new MockTextShaperImpl(), @@ -34,7 +33,7 @@ namespace Avalonia.Benchmarks.Styling return UnitTestApplication.Start(services); } - private static Styles LoadTheme() + private static Styles CreateTheme() { AssetLoader.RegisterResUriParsers(); @@ -43,11 +42,11 @@ namespace Avalonia.Benchmarks.Styling var postHost = new Style(); postHost.Resources.Add("postTheme", null); - + return new Styles { preHost, - new FluentTheme(new Uri("avares://Avalonia.Benchmarks")), + new TestStyles(50, 3, 5), postHost }; } @@ -81,11 +80,13 @@ namespace Avalonia.Benchmarks.Styling current.Child = _searchStart; } + + private const int LookupCount = 100; [Benchmark] public void FindPreResource() { - for (int i = 0; i < 100; ++i) + for (int i = 0; i < LookupCount; ++i) { _searchStart.FindResource("preTheme"); } @@ -94,7 +95,7 @@ namespace Avalonia.Benchmarks.Styling [Benchmark] public void FindPostResource() { - for (int i = 0; i < 100; ++i) + for (int i = 0; i < LookupCount; ++i) { _searchStart.FindResource("postTheme"); } @@ -103,7 +104,7 @@ namespace Avalonia.Benchmarks.Styling [Benchmark] public void FindNotExistingResource() { - for (int i = 0; i < 100; ++i) + for (int i = 0; i < LookupCount; ++i) { _searchStart.FindResource("notPresent"); } diff --git a/tests/Avalonia.Benchmarks/TestStyles.cs b/tests/Avalonia.Benchmarks/TestStyles.cs new file mode 100644 index 0000000000..be2ad7d072 --- /dev/null +++ b/tests/Avalonia.Benchmarks/TestStyles.cs @@ -0,0 +1,29 @@ +using Avalonia.Styling; + +namespace Avalonia.Benchmarks +{ + public class TestStyles : Styles + { + public TestStyles(int childStylesCount, int childInnerStyleCount, int childResourceCount) + { + for (int i = 0; i < childStylesCount; i++) + { + var childStyles = new Styles(); + + for (int j = 0; j < childInnerStyleCount; j++) + { + var childStyle = new Style(); + + for (int k = 0; k < childResourceCount; k++) + { + childStyle.Resources.Add($"resource.{i}.{j}.{k}", null); + } + + childStyles.Add(childStyle); + } + + Add(childStyles); + } + } + } +}