Skip to content

Commit

Permalink
Update Benchmark project to latest version of BenchmarkDotNet.
Browse files Browse the repository at this point in the history
  • Loading branch information
bchavez committed Jun 14, 2020
1 parent ac3ebba commit 2d6bb30
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 25 deletions.
6 changes: 6 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"commands": [
"fake"
]
},
"benchmarkdotnet.tool": {
"version": "0.12.1",
"commands": [
"dotnet-benchmark"
]
}
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,4 @@ $RECYCLE.BIN/
.DS_Store
/nuget.push.bat

/Source/Benchmark/BenchmarkDotNet.Artifacts/
1 change: 0 additions & 1 deletion Source/Benchmark/BenchGenerate.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using Bogus;

namespace Benchmark
Expand Down
108 changes: 108 additions & 0 deletions Source/Benchmark/BenchRandomNumber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System;
using System.Threading;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using Bogus;

namespace Benchmark
{
[SimpleJob(RuntimeMoniker.NetCoreApp31), SimpleJob(RuntimeMoniker.Net471)]
[MarkdownExporter, MemoryDiagnoser, RPlotExporter]
public class BenchRandomNumber
{
private NumberTests n;

[GlobalSetup]
public void Setup()
{
n = new NumberTests();
}

[Benchmark]
public int OldMethod()
{
return n.Number(int.MinValue, int.MaxValue);
}

[Benchmark]
public int BitShift()
{
return n.NumberBitShift(int.MinValue, int.MaxValue);
}

[Benchmark]
public int JDGMethod()
{
return n.NumberJDG(int.MinValue, int.MaxValue);
}
}

public class NumberTests
{
internal static Lazy<object> Locker = new Lazy<object>(() => new object(), LazyThreadSafetyMode.ExecutionAndPublication);

private readonly Random localSeed = new System.Random();

private static byte[] temp = new byte[4];

public int Number(int min = 0, int max = 1)
{
//lock any seed access, for thread safety.
lock (Locker.Value)
{
//Clamp max value, Issue #30.
max = max == int.MaxValue ? max : max + 1;
return localSeed.Next(min, max);
}
}

public int NumberBitShift(int min = 0, int max = 1)
{
//lock any seed access, for thread safety.
lock (Locker.Value)
{
// Adjust the range as needed to make max inclusive. The Random.Next function uses exclusive upper bounds.

// If max can be extended by 1, just do that.
if (max < int.MaxValue) return localSeed.Next(min, max + 1);

// If max is exactly int.MaxValue, then check if min can be used to push the range out by one the other way.
// If so, then we can simply add one to the result to put it back in the correct range.
if (min > int.MinValue) return 1 + localSeed.Next(min - 1, max);

localSeed.NextBytes(temp);
return temp[0] << 24 | temp[1] << 16 | temp[2] << 8 | temp[3];
}
}

public int NumberJDG(int min = 0, int max = 1)
{
//lock any seed access, for thread safety.
lock (Locker.Value)
{
// Adjust the range as needed to make max inclusive. The Random.Next function uses exclusive upper bounds.

// If max can be extended by 1, just do that.
if (max < int.MaxValue) return localSeed.Next(min, max + 1);

// If max is exactly int.MaxValue, then check if min can be used to push the range out by one the other way.
// If so, then we can simply add one to the result to put it back in the correct range.
if (min > int.MinValue) return 1 + localSeed.Next(min - 1, max);

// If we hit this line, then min is int.MinValue and max is int.MaxValue, which mean the caller wants a
// number from a range spanning all possible values of int. The Random class only supports exclusive
// upper bounds, period, and the upper bound must be specified as an int, so the best we can get in a
// single call is a value in the range (int.MinValue, int.MaxValue - 1). Instead, what we do is get two
// samples, one in the range (int.MinValue, -1) and the other as unbiased as possible, and using the
// second one to decide, 50% of the time we invert all the bits in the sample, shifting its range to
// (0, int.MaxValue).
var result = localSeed.Next(int.MinValue, 0);

if ((localSeed.Next() & 0x10000000) == 0)
result = ~result;

return result;
}
}
}
}
1 change: 0 additions & 1 deletion Source/Benchmark/BenchRandomSubset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using Bogus;

namespace Benchmark
Expand Down
1 change: 0 additions & 1 deletion Source/Benchmark/BenchSsn.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using Bogus;

namespace Benchmark
Expand Down
1 change: 0 additions & 1 deletion Source/Benchmark/BenchStringFill.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using Bogus;

namespace Benchmark
Expand Down
15 changes: 12 additions & 3 deletions Source/Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<Configuration>Release</Configuration>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.14" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.12.1" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 0 additions & 12 deletions Source/Benchmark/Program.cs

This file was deleted.

21 changes: 15 additions & 6 deletions Source/Benchmark/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
### Running Benchmarks

When running benchmarks, please make sure you compile this project in `Release` mode.
**Requirements:**
* **.NET 3.1 SDK** or later.
* **[`R` project for Statistical Computing](https://www.r-project.org/) version 3.3.3 (2017-03-06)** or later.
* Ensure `rscript.exe` is in your path as [instructed here](https://benchmarkdotnet.org/articles/configs/exporters.html#plots) so that plots can be generated.

Once compiled go to `\bin\Release\` and execute from the command line:
You must compile this `Benchmark` project in `Release` mode.

```csharp
dotnet build -c Release
```

After compiling in `Release` mode, execute the following command from the command line:
```
$> Benchmark.exe
$> dotnet benchmark bin\Release\netstandard2.0\Benchmark.dll
```

Your benchmark results will be in `\bin\Release\BenchmarkDotNet.Artifacts`.
Pick your benchmark to run. Your benchmark results will be in `\BenchmarkDotNet.Artifacts`.

**DO NOT** attempt to run these benchmarks through **Visual Studio**'s debugger or **F5** runner.
### Other Notes

Also, make sure you've installed [**`R`**](https://www.r-project.org/) and that `rscript.exe` is in your path as [instructed here](http://benchmarkdotnet.org/Configs/Exporters.htm#plots) so that plots can be generated.
**DO NOT** attempt to run these benchmarks through **Visual Studio**'s debugger or **F5** runner.

More on benchmarking:
http://benchmarkdotnet.org/index.htm

0 comments on commit 2d6bb30

Please sign in to comment.