Benchmark.NET usage with WPF

 


|           Method |     Toolchain |        Mean |      Error |      StdDev |   Median | Ratio | RatioSD | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
|----------------- |-------------- |------------:|-----------:|------------:|---------:|------:|--------:|------------:|------------:|------------:|--------------------:|
| LoadImageControl | .NET Core 3.0 |    450.2 us |   108.9 us |    286.8 us | 337.7 us |  0.95 |    1.37 |           - |           - |           - |             1.05 KB |
| LoadImageControl |        net471 | 13,463.7 us | 7,503.8 us | 22,125.2 us | 507.3 us |  1.00 |    0.00 |           - |           - |           - |               18 KB |



using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.CsProj;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace WPFUIBenchmark
{
public class Program
{
public static Application app;
static void Main(string[] args)
{
#if DEBUG
var test = new BenchmarkTests();
test.Setup();
test.LoadImageControl().Wait();
Task.Delay(5000).Wait();
test.Cleanup();
#else
var summary = BenchmarkRunner.Run<BenchmarkTests>();
#endif
}
public class MultipleRuntimes : ManualConfig
{
public MultipleRuntimes()
{
Add(Job.Default.With(CsProjClassicNetToolchain.Net471).AsBaseline()); // NET 4.7.1
Add(Job.Default.With(CsProjCoreToolchain.NetCoreApp30)); // .NET Core 3.0
}
}
[Config(typeof(MultipleRuntimes))]
[MemoryDiagnoser]
public class BenchmarkTests
{
System.Windows.Application app;
[GlobalSetup]
public void Setup()
{
app = UIInitializer.CreateUIApplication(1024,768);
}
[GlobalCleanup]
public void Cleanup()
{
app.Dispatcher.Invoke(() =>
{
app.Shutdown();
app = null;
});
}
[Benchmark]
public Task LoadImageControl()
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
app.Dispatcher.Invoke(async () =>
{
Image img = new Image() { Stretch = System.Windows.Media.Stretch.Fill, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };
img.LayoutUpdated += (s, e) =>
{
if (img.ActualWidth > 0)
tcs.TrySetResult(null);
};
TaskCompletionSource<object> tcs2 = new TaskCompletionSource<object>();
img.Loaded += (s, e) => tcs.SetResult(null);
app.MainWindow.Content = img;
await tcs.Task;
var imageSource = new System.Windows.Media.Imaging.BitmapImage();
imageSource.CreateOptions = System.Windows.Media.Imaging.BitmapCreateOptions.DelayCreation;
imageSource.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.None;
imageSource.BeginInit();
imageSource.UriSource = new Uri("image.jpg", UriKind.Relative);
imageSource.EndInit();
img.Source = imageSource;
});
return tcs.Task;
}
}
}
}
view raw Program.cs hosted with ❤ by GitHub
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WPFUIBenchmark
{
class UIInitializer
{
public static System.Windows.Application CreateUIApplication(int width = 500, int height = 250)
{
var waitForApplicationRun = new TaskCompletionSource<System.Windows.Application>();
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
var application = new System.Windows.Application();
application.Startup += (s, e) =>
{
application.Dispatcher.Invoke(() =>
{
var window = application.MainWindow = new System.Windows.Window() { Width = width, Height = height };
window.Content = new System.Windows.Controls.ContentControl();
window.Show();
if (window.IsLoaded)
{
waitForApplicationRun.TrySetResult(application);
}
else
{
window.Loaded += (s2, e2) => waitForApplicationRun.TrySetResult(application);
}
});
};
application.Run();
}));
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
waitForApplicationRun.Task.Wait();
return waitForApplicationRun.Task.Result;
}
}
}
Run in RELEASE mode to get the benchmark report