Skip to content

Commit

Permalink
feat: generate benchmarks via t4 (#105)
Browse files Browse the repository at this point in the history
Co-authored-by: Glenn <[email protected]>
  • Loading branch information
cabauman and glennawatson authored Dec 13, 2020
1 parent 9ba4791 commit 610bf06
Show file tree
Hide file tree
Showing 6 changed files with 757 additions and 218 deletions.
270 changes: 198 additions & 72 deletions src/ReactiveMarbles.PropertyChanged.Benchmarks/BindBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,63 @@
// Copyright (c) 2019-2020 ReactiveUI Association Incorporated. All rights reserved.
// Copyright (c) 2019-2020 ReactiveUI Association Incorporated. All rights reserved.
// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;

using ReactiveMarbles.PropertyChanged.Benchmarks.Moqs;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using New = ReactiveMarbles.PropertyChanged.BindExtensions;
using Old = ReactiveMarbles.PropertyChanged.Benchmarks.Legacy.BindExtensions;
using UI = ReactiveUI.PropertyBindingMixins;

#nullable disable
using Old = ReactiveMarbles.PropertyChanged.Benchmarks.Legacy.BindExtensions;
using New = ReactiveMarbles.PropertyChanged.BindExtensions;

namespace ReactiveMarbles.PropertyChanged.Benchmarks
{
/// <summary>
/// Benchmarks for the property changed.
/// Benchmarks for binding.
/// </summary>
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[MemoryDiagnoser]
[MarkdownExporterAttribute.GitHub]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
public class BindBenchmarks
{
private TestClass _from;
private TestClass _to;
private IDisposable _binding;

/// <summary>
/// The parameters for the tests.
/// The number mutations to perform.
/// </summary>
[SuppressMessage("Design", "SA1401: field should be private", Justification = "needed by benchmark")]
[SuppressMessage("Design", "CA1051: field should be private", Justification = "needed by benchmark")]
[Params(1, 2, 3)]
public int Depth;

[SuppressMessage("Design", "SA1401: field should be private", Justification = "needed by benchmark")]
[SuppressMessage("Design", "CA1051: field should be private", Justification = "needed by benchmark")]
[Params( 1, 10, 100, 1000)]
[Params(1, 10, 100, 1000)]
public int Changes;

private TestClass _from;
private TestClass _to;
private IDisposable _binding;
private Expression<Func<TestClass, int>> _propertyExpression;

[GlobalSetup(Targets = new[] { nameof(BindAndChangeUI), nameof(BindAndChangeOld), nameof(BindAndChangeNew), nameof(NoBind) })]
public void CommonSetup()
[GlobalSetup(Targets = new[] { "BindAndChange_Depth1_UI", "BindAndChange_Depth1_Old", "BindAndChange_Depth1_New" })]
public void Depth1Setup()
{
_from = new TestClass(1);
_to = new TestClass(1);
}

[GlobalSetup(Targets = new[] { "BindAndChange_Depth2_UI", "BindAndChange_Depth2_Old", "BindAndChange_Depth2_New" })]
public void Depth2Setup()
{
_from = new TestClass(Depth);
_to = new TestClass(Depth);
_propertyExpression = TestClass.GetValuePropertyExpression(Depth);
_from = new TestClass(2);
_to = new TestClass(2);
}

//[BenchmarkCategory("No Binding")]
//[Benchmark(Baseline = true)]
public void NoBind()
[GlobalSetup(Targets = new[] { "BindAndChange_Depth3_UI", "BindAndChange_Depth3_Old", "BindAndChange_Depth3_New" })]
public void Depth3Setup()
{
// We loop through the changes, alternating mutations to the source and destination
// at every depth.
var d2 = Depth * 2;
_from = new TestClass(3);
_to = new TestClass(3);
}

public void PerformMutations(int depth)
{
// We loop through the changes, alternating mutations to the source and destination at every depth.
var d2 = depth * 2;
for (var i = 0; i < Changes; ++i)
{
var a = i % d2;
Expand All @@ -68,80 +66,208 @@ public void NoBind()
}
}

[BenchmarkCategory("Bind and Change")]
[BenchmarkCategory("Bind and Change Depth 1")]
[Benchmark(Baseline = true)]
public void BindAndChange_Depth1_UI()
{
using var binding = UI.Bind(_from, _to, x => x.Value, x => x.Value);
PerformMutations(1);
}

[BenchmarkCategory("Bind and Change Depth 1")]
[Benchmark]
public void BindAndChange_Depth1_Old()
{
using var binding = Old.Bind(_from, _to, x => x.Value, x => x.Value);
PerformMutations(1);
}

[BenchmarkCategory("Bind and Change Depth 1")]
[Benchmark]
public void BindAndChange_Depth1_New()
{
using var binding = New.Bind(_from, _to, x => x.Value, x => x.Value);
PerformMutations(1);
}

[BenchmarkCategory("Bind and Change Depth 2")]
[Benchmark(Baseline = true)]
public void BindAndChange_Depth2_UI()
{
using var binding = UI.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
PerformMutations(2);
}

[BenchmarkCategory("Bind and Change Depth 2")]
[Benchmark]
public void BindAndChange_Depth2_Old()
{
using var binding = Old.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
PerformMutations(2);
}

[BenchmarkCategory("Bind and Change Depth 2")]
[Benchmark]
public void BindAndChange_Depth2_New()
{
using var binding = New.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
PerformMutations(2);
}

[BenchmarkCategory("Bind and Change Depth 3")]
[Benchmark(Baseline = true)]
public void BindAndChangeUI()
public void BindAndChange_Depth3_UI()
{
using var binding = UI.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
PerformMutations(3);
}

[BenchmarkCategory("Bind and Change Depth 3")]
[Benchmark]
public void BindAndChange_Depth3_Old()
{
using var binding = Old.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
PerformMutations(3);
}

[BenchmarkCategory("Bind and Change Depth 3")]
[Benchmark]
public void BindAndChange_Depth3_New()
{
using var binding = New.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
PerformMutations(3);
}

[GlobalSetup(Target = "Change_Depth1_UI")]
public void Change_Depth1_UISetup()
{
Depth1Setup();
_binding = UI.Bind(_from, _to, x => x.Value, x => x.Value);
}

[BenchmarkCategory("Change Depth 1")]
[Benchmark(Baseline = true)]
public void Change_Depth1_UI()
{
PerformMutations(1);
}

[GlobalSetup(Target = "Change_Depth1_Old")]
public void Change_Depth1_OldSetup()
{
Depth1Setup();
_binding = Old.Bind(_from, _to, x => x.Value, x => x.Value);
}

[BenchmarkCategory("Change Depth 1")]
[Benchmark]
public void Change_Depth1_Old()
{
using var binding = UI.Bind(_from, _to, _propertyExpression, _propertyExpression);
PerformMutations(1);
}

NoBind();
[GlobalSetup(Target = "Change_Depth1_New")]
public void Change_Depth1_NewSetup()
{
Depth1Setup();
_binding = New.Bind(_from, _to, x => x.Value, x => x.Value);
}

[BenchmarkCategory("Bind and Change")]
[BenchmarkCategory("Change Depth 1")]
[Benchmark]
public void BindAndChangeOld()
public void Change_Depth1_New()
{
using var binding = Old.Bind(_from, _to, _propertyExpression, _propertyExpression);

NoBind();
PerformMutations(1);
}

[BenchmarkCategory("Bind and Change")]
[GlobalSetup(Target = "Change_Depth2_UI")]
public void Change_Depth2_UISetup()
{
Depth2Setup();
_binding = UI.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
}

[BenchmarkCategory("Change Depth 2")]
[Benchmark(Baseline = true)]
public void Change_Depth2_UI()
{
PerformMutations(2);
}

[GlobalSetup(Target = "Change_Depth2_Old")]
public void Change_Depth2_OldSetup()
{
Depth2Setup();
_binding = Old.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
}

[BenchmarkCategory("Change Depth 2")]
[Benchmark]
public void BindAndChangeNew()
public void Change_Depth2_Old()
{
PerformMutations(2);
}

[GlobalSetup(Target = "Change_Depth2_New")]
public void Change_Depth2_NewSetup()
{
using var binding = New.Bind(_from, _to, _propertyExpression, _propertyExpression);
Depth2Setup();
_binding = New.Bind(_from, _to, x => x.Child.Value, x => x.Child.Value);
}

NoBind();
[BenchmarkCategory("Change Depth 2")]
[Benchmark]
public void Change_Depth2_New()
{
PerformMutations(2);
}

[GlobalSetup(Target = nameof(ChangeUI))]
public void ChangUISetup()
[GlobalSetup(Target = "Change_Depth3_UI")]
public void Change_Depth3_UISetup()
{
CommonSetup();
_binding = UI.Bind(_from, _to, _propertyExpression, _propertyExpression);
Depth3Setup();
_binding = UI.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
}

[BenchmarkCategory("Change")]
[BenchmarkCategory("Change Depth 3")]
[Benchmark(Baseline = true)]
public void ChangeUI()
public void Change_Depth3_UI()
{
NoBind();
PerformMutations(3);
}

[GlobalSetup(Target = nameof(ChangeOld))]
public void ChangOldSetup()
[GlobalSetup(Target = "Change_Depth3_Old")]
public void Change_Depth3_OldSetup()
{
CommonSetup();
_binding = Old.Bind(_from, _to, _propertyExpression, _propertyExpression);
Depth3Setup();
_binding = Old.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
}

[BenchmarkCategory("Change")]
[BenchmarkCategory("Change Depth 3")]
[Benchmark]
public void ChangeOld()
public void Change_Depth3_Old()
{
NoBind();
PerformMutations(3);
}

[GlobalSetup(Target = nameof(ChangeNew))]
public void ChangNewSetup()
[GlobalSetup(Target = "Change_Depth3_New")]
public void Change_Depth3_NewSetup()
{
CommonSetup();
_binding = New.Bind(_from, _to, _propertyExpression, _propertyExpression);
Depth3Setup();
_binding = New.Bind(_from, _to, x => x.Child.Child.Value, x => x.Child.Child.Value);
}

[BenchmarkCategory("Change")]
[BenchmarkCategory("Change Depth 3")]
[Benchmark]
public void ChangeNew()
public void Change_Depth3_New()
{
NoBind();
PerformMutations(3);
}

[GlobalCleanup(Targets = new[] { nameof(ChangeUI), nameof(ChangeOld), nameof(ChangeNew) })]
[GlobalCleanup(Targets = new[] { "Change_Depth1_UI", "Change_Depth1_Old", "Change_Depth1_New", "Change_Depth2_UI", "Change_Depth2_Old", "Change_Depth2_New", "Change_Depth3_UI", "Change_Depth3_Old", "Change_Depth3_New" })]
public void GlobalCleanup()
{
// Disposing logic
_binding!.Dispose();
_binding.Dispose();
}
}
}
}
Loading

0 comments on commit 610bf06

Please sign in to comment.