Skip to content

Instantly share code, notes, and snippets.

@Demuirgos
Last active October 16, 2022 16:00
Show Gist options
  • Save Demuirgos/9074f2785367dd80205436e66b37c2cd to your computer and use it in GitHub Desktop.
Save Demuirgos/9074f2785367dd80205436e66b37c2cd to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkRunner.Run<MonitorCompare>();
static class Log {
private static int counter = 0;
public static void LogResult(long value) {
counter++;
}
}
class DestructorCounter {
private Stopwatch stopwatch = new Stopwatch();
public DestructorCounter() {
stopwatch.Start();
}
~DestructorCounter() {
Log.LogResult(stopwatch.ElapsedTicks);
}
}
class DeferedCounter : Defer<Stopwatch> {
private DeferedCounter(Stopwatch res, Action<Stopwatch> start, Action<Stopwatch> end) : base(res, start, end) {}
public DeferedCounter() : base(new Stopwatch(), (resource) => resource.Start(), (resource) => Log.LogResult(resource.ElapsedTicks)) {}
}
class DeferedCounter2 : Defer<Stopwatch> {
private DeferedCounter2(Stopwatch res, Action<Stopwatch> start, Action<Stopwatch> end) : base(res, start, end) {}
public DeferedCounter2() : base(new Stopwatch(), (resource) => resource.Start(), (resource) => Log.LogResult(resource.ElapsedTicks)) {}
}
class Defer<T> : IDisposable {
public T Resource;
internal Action<T> defered {get; set;}
internal Action<T> urgent {get; set;}
public Defer() {}
public Defer(T res, Action<T> onStart, Action<T> onEnd) {
Resource = res;
(urgent, defered) = (onStart, onEnd);
urgent?.Invoke(Resource);
}
public void Dispose() {
defered?.Invoke(Resource);
}
}
[MemoryDiagnoser]
public class MonitorCompare
{
static Action work = () => {
int i= 0;
while( i< 10000) {
if(i % 2 == 0) {
i--;
} else {
i+=2;
}
}
};
[Benchmark]
public void ManualMethod() => ManualMethod(work);
void ManualMethod(Action someWork) {
var watch = new Stopwatch();
watch.Start();
someWork();
Log.LogResult(watch.ElapsedTicks);
}
[Benchmark]
public void TryFinallyMethod() => TryFinallyMethod(work);
void TryFinallyMethod(Action someWork) {
var watch = new Stopwatch();
try {
someWork();
} finally {
Log.LogResult(watch.ElapsedTicks);
}
}
[Benchmark]
public void DeferMethod() => ManualMethod(work);
void DeferMethod(Action someWork) {
var watch = new Stopwatch();
using(var manager = new Defer<Stopwatch>(watch, (watch) => watch.Start(), (watch) => Log.LogResult(watch.ElapsedTicks))){
someWork();
}
}
[Benchmark]
public void UsingMethod() => ManualMethod(work);
void UsingMethod(Action someWork) {
using(var counter = new DeferedCounter()) {
someWork();
}
}
[Benchmark]
public void Using2Method() => ManualMethod(work);
void Using2Method(Action someWork) {
using var counter = new DeferedCounter2();
someWork();
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="benchmarkDotNet" Version="0.13.2" />
</ItemGroup>
</Project>
// * Detailed results *
MonitorCompare.ManualMethod: DefaultJob
Runtime = .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2; GC = Concurrent Workstation
Mean = 6.077 us, StdErr = 0.033 us (0.54%), N = 33, StdDev = 0.190 us
Min = 5.813 us, Q1 = 5.939 us, Median = 6.055 us, Q3 = 6.171 us, Max = 6.550 us
IQR = 0.232 us, LowerFence = 5.590 us, UpperFence = 6.519 us
ConfidenceInterval = [5.957 us; 6.196 us] (CI 99.9%), Margin = 0.120 us (1.97% of Mean)
Skewness = 0.84, Kurtosis = 3.01, MValue = 2
-------------------- Histogram --------------------
[5.735 us ; 6.001 us) | @@@@@@@@@@@@@@@
[6.001 us ; 6.192 us) | @@@@@@@@@@@
[6.192 us ; 6.423 us) | @@@@
[6.423 us ; 6.578 us) | @@@
---------------------------------------------------
MonitorCompare.TryFinallyMethod: DefaultJob
Runtime = .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2; GC = Concurrent Workstation
Mean = 6.085 us, StdErr = 0.034 us (0.55%), N = 42, StdDev = 0.218 us
Min = 5.761 us, Q1 = 5.941 us, Median = 6.006 us, Q3 = 6.234 us, Max = 6.664 us
IQR = 0.293 us, LowerFence = 5.501 us, UpperFence = 6.674 us
ConfidenceInterval = [5.966 us; 6.204 us] (CI 99.9%), Margin = 0.119 us (1.96% of Mean)
Skewness = 0.79, Kurtosis = 2.74, MValue = 2.2
-------------------- Histogram --------------------
[5.727 us ; 5.897 us) | @@@@@
[5.897 us ; 6.062 us) | @@@@@@@@@@@@@@@@@@@@
[6.062 us ; 6.202 us) | @@@@@
[6.202 us ; 6.367 us) | @@@@@@@
[6.367 us ; 6.545 us) | @@@@
[6.545 us ; 6.746 us) | @
---------------------------------------------------
MonitorCompare.DeferMethod: DefaultJob
Runtime = .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2; GC = Concurrent Workstation
Mean = 5.857 us, StdErr = 0.032 us (0.54%), N = 32, StdDev = 0.179 us
Min = 5.473 us, Q1 = 5.726 us, Median = 5.840 us, Q3 = 5.968 us, Max = 6.294 us
IQR = 0.242 us, LowerFence = 5.363 us, UpperFence = 6.330 us
ConfidenceInterval = [5.742 us; 5.972 us] (CI 99.9%), Margin = 0.115 us (1.96% of Mean)
Skewness = 0.23, Kurtosis = 2.77, MValue = 2
-------------------- Histogram --------------------
[5.399 us ; 5.546 us) | @
[5.546 us ; 5.702 us) | @@@
[5.702 us ; 5.850 us) | @@@@@@@@@@@@@
[5.850 us ; 6.043 us) | @@@@@@@@@@@@
[6.043 us ; 6.301 us) | @@@
---------------------------------------------------
MonitorCompare.UsingMethod: DefaultJob
Runtime = .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2; GC = Concurrent Workstation
Mean = 5.898 us, StdErr = 0.025 us (0.42%), N = 13, StdDev = 0.089 us
Min = 5.765 us, Q1 = 5.820 us, Median = 5.907 us, Q3 = 5.964 us, Max = 6.074 us
IQR = 0.144 us, LowerFence = 5.604 us, UpperFence = 6.179 us
ConfidenceInterval = [5.792 us; 6.004 us] (CI 99.9%), Margin = 0.106 us (1.80% of Mean)
Skewness = 0.35, Kurtosis = 1.98, MValue = 2
-------------------- Histogram --------------------
[5.716 us ; 5.920 us) | @@@@@@@@
[5.920 us ; 6.124 us) | @@@@@
---------------------------------------------------
MonitorCompare.Using2Method: DefaultJob
Runtime = .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2; GC = Concurrent Workstation
Mean = 5.903 us, StdErr = 0.031 us (0.53%), N = 36, StdDev = 0.188 us
Min = 5.489 us, Q1 = 5.780 us, Median = 5.871 us, Q3 = 6.045 us, Max = 6.263 us
IQR = 0.265 us, LowerFence = 5.383 us, UpperFence = 6.442 us
ConfidenceInterval = [5.791 us; 6.016 us] (CI 99.9%), Margin = 0.113 us (1.91% of Mean)
Skewness = -0.04, Kurtosis = 2.44, MValue = 2
-------------------- Histogram --------------------
[5.433 us ; 5.582 us) | @@
[5.582 us ; 5.764 us) | @@@@@
[5.764 us ; 5.913 us) | @@@@@@@@@@@@@@@
[5.913 us ; 6.132 us) | @@@@@@@@@@
[6.132 us ; 6.279 us) | @@@@
---------------------------------------------------
// * Summary *
BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.674)
Intel Core i5-8265U CPU 1.60GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.402
[Host] : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2
DefaultJob : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|----------------- |---------:|----------:|----------:|-------:|----------:|
| ManualMethod | 6.077 us | 0.1196 us | 0.1896 us | 0.0076 | 40 B |
| TryFinallyMethod | 6.085 us | 0.1193 us | 0.2182 us | 0.0076 | 40 B |
| DeferMethod | 5.857 us | 0.1149 us | 0.1789 us | 0.0076 | 40 B |
| UsingMethod | 5.898 us | 0.1060 us | 0.0886 us | 0.0076 | 40 B |
| Using2Method | 5.903 us | 0.1125 us | 0.1880 us | 0.0076 | 40 B |
// * Hints *
Outliers
MonitorCompare.ManualMethod: Default -> 5 outliers were removed (6.78 us..9.04 us)
MonitorCompare.TryFinallyMethod: Default -> 1 outlier was removed (6.76 us)
MonitorCompare.DeferMethod: Default -> 2 outliers were removed (6.66 us, 9.12 us)
MonitorCompare.UsingMethod: Default -> 2 outliers were removed (6.42 us, 6.49 us)
MonitorCompare.Using2Method: Default -> 1 outlier was removed (6.51 us)
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen0 : GC Generation 0 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 us : 1 Microsecond (0.000001 sec)
// * Diagnostic Output - MemoryDiagnoser *
// ***** BenchmarkRunner: End *****
Run time: 00:02:59 (179.38 sec), executed benchmarks: 5
Global total time: 00:03:11 (191.23 sec), executed benchmarks: 5
// * Artifacts cleanup *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment