diff --git a/.gitignore b/.gitignore
index 940794e..a1b7e6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+BenchmarkDotNet.Artifacts/
# Visual Studio 2015 cache/options directory
.vs/
diff --git a/Ben.Demystifier.sln b/Ben.Demystifier.sln
index 2cf7ecd..5945254 100644
--- a/Ben.Demystifier.sln
+++ b/Ben.Demystifier.sln
@@ -20,9 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
appveyor.yml = appveyor.yml
build.ps1 = build.ps1
directory.build.props = directory.build.props
+ README.md = README.md
version.json = version.json
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ben.Demystifier.Benchmarks", "test\Ben.Demystifier.Benchmarks\Ben.Demystifier.Benchmarks.csproj", "{EF5557DF-C48E-4999-846C-D99A92E86373}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -41,6 +44,10 @@ Global
{E161FC12-53C2-47CD-A5FC-3684B86723A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E161FC12-53C2-47CD-A5FC-3684B86723A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E161FC12-53C2-47CD-A5FC-3684B86723A9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EF5557DF-C48E-4999-846C-D99A92E86373}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+ {EF5557DF-C48E-4999-846C-D99A92E86373}.Debug|Any CPU.Build.0 = Release|Any CPU
+ {EF5557DF-C48E-4999-846C-D99A92E86373}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF5557DF-C48E-4999-846C-D99A92E86373}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -49,6 +56,7 @@ Global
{5410A056-89AB-4912-BD1E-A63616AD91D0} = {A2FCCAAC-BE90-4F7E-B95F-A72D46DDD6B3}
{B9E150B0-AEEB-4D98-8BE1-92C1296699A2} = {59CA6310-4AA5-4093-95D4-472B94DC0CD4}
{E161FC12-53C2-47CD-A5FC-3684B86723A9} = {455921D3-DD54-4355-85CF-F4009DF2AB70}
+ {EF5557DF-C48E-4999-846C-D99A92E86373} = {59CA6310-4AA5-4093-95D4-472B94DC0CD4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {841B7D5F-E810-4F94-A529-002C7E075216}
diff --git a/README.md b/README.md
index f2f2946..944d392 100644
--- a/README.md
+++ b/README.md
@@ -158,3 +158,11 @@ Which is far less helpful, and close to jibberish in places
* **return types**
Skipped entirely from method signature
+
+### Benchmarks
+
+To run benchmarks from the repository root:
+```
+dotnet run -p .\test\Ben.Demystifier.Benchmarks\ -c Release -f netcoreapp2.0 All
+```
+Note: we're only kicking off via `netcoreapp2.0`, benchmarks will run for all configured platforms like `net462`.
diff --git a/test/Ben.Demystifier.Benchmarks/Ben.Demystifier.Benchmarks.csproj b/test/Ben.Demystifier.Benchmarks/Ben.Demystifier.Benchmarks.csproj
new file mode 100644
index 0000000..75d99f0
--- /dev/null
+++ b/test/Ben.Demystifier.Benchmarks/Ben.Demystifier.Benchmarks.csproj
@@ -0,0 +1,11 @@
+
+
+ netcoreapp2.0;net462
+ Release
+ Exe
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Ben.Demystifier.Benchmarks/Exceptions.cs b/test/Ben.Demystifier.Benchmarks/Exceptions.cs
new file mode 100644
index 0000000..0bc8881
--- /dev/null
+++ b/test/Ben.Demystifier.Benchmarks/Exceptions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Diagnostics;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Attributes.Jobs;
+
+namespace Ben.Demystifier.Benchmarks
+{
+ [ClrJob, CoreJob]
+ [Config(typeof(Config))]
+ public class ExceptionTests
+ {
+ [Benchmark(Baseline = true, Description = ".ToString()")]
+ public string Baseline() => new Exception().ToString();
+
+ [Benchmark(Description = "Demystify().ToString()")]
+ public string Demystify() => new Exception().Demystify().ToString();
+ }
+}
diff --git a/test/Ben.Demystifier.Benchmarks/Program.cs b/test/Ben.Demystifier.Benchmarks/Program.cs
new file mode 100644
index 0000000..4b8a7e4
--- /dev/null
+++ b/test/Ben.Demystifier.Benchmarks/Program.cs
@@ -0,0 +1,48 @@
+using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Running;
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Ben.Demystifier.Benchmarks
+{
+ public static class Program
+ {
+ private const string BenchmarkSuffix = "Tests";
+
+ public static void Main(string[] args)
+ {
+ var benchmarks = Assembly.GetEntryAssembly()
+ .DefinedTypes.Where(t => t.Name.EndsWith(BenchmarkSuffix))
+ .ToDictionary(t => t.Name.Substring(0, t.Name.Length - BenchmarkSuffix.Length), t => t, StringComparer.OrdinalIgnoreCase);
+
+ if (args.Length > 0 && args[0].Equals("all", StringComparison.OrdinalIgnoreCase))
+ {
+ Console.WriteLine("Running full benchmarks suite");
+ benchmarks.Select(pair => pair.Value).ToList().ForEach(action => BenchmarkRunner.Run(action));
+ return;
+ }
+
+ if (args.Length == 0 || !benchmarks.ContainsKey(args[0]))
+ {
+ Console.WriteLine("Please, select benchmark, list of available:");
+ benchmarks
+ .Select(pair => pair.Key)
+ .ToList()
+ .ForEach(Console.WriteLine);
+ Console.WriteLine("All");
+ return;
+ }
+
+ BenchmarkRunner.Run(benchmarks[args[0]]);
+
+ Console.Read();
+ }
+ }
+
+ internal class Config : ManualConfig
+ {
+ public Config() => Add(new MemoryDiagnoser());
+ }
+}