-
-
Notifications
You must be signed in to change notification settings - Fork 945
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add BenchmarkDotNet.Diagnostics.dotTrace
- Loading branch information
1 parent
a260bd3
commit ff6e8d9
Showing
20 changed files
with
661 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
uid: BenchmarkDotNet.Samples.IntroDotTraceDiagnoser | ||
--- | ||
|
||
## Sample: IntroDotTraceDiagnoser | ||
|
||
If you want to get a performance profile of your benchmarks, just add the `[DotTraceDiagnoser]` attribute, as shown below. | ||
As a result, BenchmarkDotNet performs bonus benchmark runs using attached | ||
[dotTrace Command-Line Profiler](https://www.jetbrains.com/help/profiler/Performance_Profiling__Profiling_Using_the_Command_Line.html). | ||
The obtained snapshots are saved to the `artifacts` folder. | ||
These snapshots can be opened using the [standalone dotTrace](https://www.jetbrains.com/profiler/), | ||
or [dotTrace in Rider](https://www.jetbrains.com/help/rider/Performance_Profiling.html). | ||
|
||
### Source code | ||
|
||
[!code-csharp[IntroDotTraceDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroDotTraceDiagnoser.cs)] | ||
|
||
### Links | ||
|
||
* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDotTraceDiagnoser | ||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using BenchmarkDotNet.Diagnostics.dotTrace; | ||
|
||
namespace BenchmarkDotNet.Samples | ||
{ | ||
// Enables dotTrace profiling for all jobs | ||
[DotTraceDiagnoser] | ||
// Adds the default "external-process" job | ||
// Profiling is performed using dotTrace command-line Tools | ||
// See: https://www.jetbrains.com/help/profiler/Performance_Profiling__Profiling_Using_the_Command_Line.html | ||
[SimpleJob] | ||
// Adds an "in-process" job | ||
// Profiling is performed using dotTrace SelfApi | ||
// NuGet reference: https://www.nuget.org/packages/JetBrains.Profiler.SelfApi | ||
[InProcess] | ||
public class IntroDotTraceDiagnoser | ||
{ | ||
[Benchmark] | ||
public void Fibonacci() => Fibonacci(30); | ||
|
||
private static int Fibonacci(int n) | ||
{ | ||
return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<Import Project="..\..\build\common.props" /> | ||
<PropertyGroup> | ||
<TargetFrameworks>net6.0;net462;netcoreapp3.1</TargetFrameworks> | ||
<NoWarn>$(NoWarn);1591</NoWarn> | ||
<AssemblyTitle>BenchmarkDotNet.Diagnostics.dotTrace</AssemblyTitle> | ||
<AssemblyName>BenchmarkDotNet.Diagnostics.dotTrace</AssemblyName> | ||
<PackageId>BenchmarkDotNet.Diagnostics.dotTrace</PackageId> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\BenchmarkDotNet\BenchmarkDotNet.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="JetBrains.Profiler.SelfApi" Version="2.4.2" /> | ||
</ItemGroup> | ||
|
||
</Project> |
148 changes: 148 additions & 0 deletions
148
src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.IO; | ||
using System.Linq; | ||
using BenchmarkDotNet.Analysers; | ||
using BenchmarkDotNet.Diagnosers; | ||
using BenchmarkDotNet.Engines; | ||
using BenchmarkDotNet.Exporters; | ||
using BenchmarkDotNet.Extensions; | ||
using BenchmarkDotNet.Jobs; | ||
using BenchmarkDotNet.Loggers; | ||
using BenchmarkDotNet.Portability; | ||
using BenchmarkDotNet.Reports; | ||
using BenchmarkDotNet.Running; | ||
using BenchmarkDotNet.Toolchains; | ||
using BenchmarkDotNet.Validators; | ||
using RunMode = BenchmarkDotNet.Diagnosers.RunMode; | ||
|
||
namespace BenchmarkDotNet.Diagnostics.dotTrace | ||
{ | ||
public class DotTraceDiagnoser : IProfiler | ||
{ | ||
private readonly Uri nugetUrl; | ||
private readonly string toolsDownloadFolder; | ||
|
||
public DotTraceDiagnoser(Uri nugetUrl = null, string toolsDownloadFolder = null) | ||
{ | ||
this.nugetUrl = nugetUrl; | ||
this.toolsDownloadFolder = toolsDownloadFolder; | ||
} | ||
|
||
public IEnumerable<string> Ids => new[] { "DotTrace" }; | ||
public string ShortName => "dotTrace"; | ||
|
||
public RunMode GetRunMode(BenchmarkCase benchmarkCase) | ||
{ | ||
return IsSupported(benchmarkCase.Job.Environment.GetRuntime().RuntimeMoniker) ? RunMode.ExtraRun : RunMode.None; | ||
} | ||
|
||
private readonly List<string> snapshotFilePaths = new (); | ||
|
||
public void Handle(HostSignal signal, DiagnoserActionParameters parameters) | ||
{ | ||
var job = parameters.BenchmarkCase.Job; | ||
bool isInProcess = job.GetToolchain().IsInProcess; | ||
var logger = parameters.Config.GetCompositeLogger(); | ||
DotTraceToolBase tool = isInProcess | ||
? new InProcessDotTraceTool(logger, nugetUrl, downloadTo: toolsDownloadFolder) | ||
: new ExternalDotTraceTool(logger, nugetUrl, downloadTo: toolsDownloadFolder); | ||
|
||
var runtimeMoniker = job.Environment.GetRuntime().RuntimeMoniker; | ||
if (!IsSupported(runtimeMoniker)) | ||
{ | ||
logger.WriteLineError($"Runtime '{runtimeMoniker}' is not supported by dotTrace"); | ||
return; | ||
} | ||
|
||
switch (signal) | ||
{ | ||
case HostSignal.BeforeAnythingElse: | ||
tool.Init(parameters); | ||
break; | ||
case HostSignal.BeforeActualRun: | ||
snapshotFilePaths.Add(tool.Start(parameters)); | ||
break; | ||
case HostSignal.AfterActualRun: | ||
tool.Stop(parameters); | ||
break; | ||
} | ||
} | ||
|
||
public IEnumerable<IExporter> Exporters => Enumerable.Empty<IExporter>(); | ||
public IEnumerable<IAnalyser> Analysers => Enumerable.Empty<IAnalyser>(); | ||
|
||
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) | ||
{ | ||
var runtimeMonikers = validationParameters.Benchmarks.Select(b => b.Job.Environment.GetRuntime().RuntimeMoniker).Distinct(); | ||
foreach (var runtimeMoniker in runtimeMonikers) | ||
{ | ||
if (!IsSupported(runtimeMoniker)) | ||
yield return new ValidationError(true, $"Runtime '{runtimeMoniker}' is not supported by dotTrace"); | ||
} | ||
} | ||
|
||
internal static bool IsSupported(RuntimeMoniker runtimeMoniker) | ||
{ | ||
switch (runtimeMoniker) | ||
{ | ||
case RuntimeMoniker.HostProcess: | ||
case RuntimeMoniker.Net461: | ||
case RuntimeMoniker.Net462: | ||
case RuntimeMoniker.Net47: | ||
case RuntimeMoniker.Net471: | ||
case RuntimeMoniker.Net472: | ||
case RuntimeMoniker.Net48: | ||
case RuntimeMoniker.Net481: | ||
case RuntimeMoniker.Net50: | ||
case RuntimeMoniker.Net60: | ||
case RuntimeMoniker.Net70: | ||
case RuntimeMoniker.Net80: | ||
return true; | ||
case RuntimeMoniker.NotRecognized: | ||
case RuntimeMoniker.Mono: | ||
case RuntimeMoniker.NativeAot60: | ||
case RuntimeMoniker.NativeAot70: | ||
case RuntimeMoniker.NativeAot80: | ||
case RuntimeMoniker.Wasm: | ||
case RuntimeMoniker.WasmNet50: | ||
case RuntimeMoniker.WasmNet60: | ||
case RuntimeMoniker.WasmNet70: | ||
case RuntimeMoniker.WasmNet80: | ||
case RuntimeMoniker.MonoAOTLLVM: | ||
case RuntimeMoniker.MonoAOTLLVMNet60: | ||
case RuntimeMoniker.MonoAOTLLVMNet70: | ||
case RuntimeMoniker.MonoAOTLLVMNet80: | ||
case RuntimeMoniker.Mono60: | ||
case RuntimeMoniker.Mono70: | ||
case RuntimeMoniker.Mono80: | ||
#pragma warning disable CS0618 // Type or member is obsolete | ||
case RuntimeMoniker.NetCoreApp50: | ||
#pragma warning restore CS0618 // Type or member is obsolete | ||
return false; | ||
case RuntimeMoniker.NetCoreApp20: | ||
case RuntimeMoniker.NetCoreApp21: | ||
case RuntimeMoniker.NetCoreApp22: | ||
return RuntimeInformation.IsWindows(); | ||
case RuntimeMoniker.NetCoreApp30: | ||
case RuntimeMoniker.NetCoreApp31: | ||
return RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux(); | ||
default: | ||
throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $"Runtime moniker {runtimeMoniker} is not supported"); | ||
} | ||
} | ||
|
||
public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => ImmutableArray<Metric>.Empty; | ||
|
||
public void DisplayResults(ILogger logger) | ||
{ | ||
if (snapshotFilePaths.Any()) | ||
{ | ||
logger.WriteLineInfo("The following dotTrace snapshots were generated:"); | ||
foreach (string snapshotFilePath in snapshotFilePaths) | ||
logger.WriteLineInfo($"* {snapshotFilePath}"); | ||
} | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using BenchmarkDotNet.Configs; | ||
|
||
namespace BenchmarkDotNet.Diagnostics.dotTrace | ||
{ | ||
[AttributeUsage(AttributeTargets.Class)] | ||
public class DotTraceDiagnoserAttribute : Attribute, IConfigSource | ||
{ | ||
public IConfig Config { get; } | ||
|
||
public DotTraceDiagnoserAttribute() | ||
{ | ||
Config = ManualConfig.CreateEmpty().AddDiagnoser(new DotTraceDiagnoser()); | ||
} | ||
|
||
public DotTraceDiagnoserAttribute(Uri nugetUrl = null, string toolsDownloadFolder = null) | ||
{ | ||
Config = ManualConfig.CreateEmpty().AddDiagnoser(new DotTraceDiagnoser(nugetUrl, toolsDownloadFolder)); | ||
} | ||
} | ||
} |
Oops, something went wrong.