Skip to content

Commit c41e2bf

Browse files
committed
Fix memory benchmarking in .NET 4.6
1 parent a9718fb commit c41e2bf

File tree

4 files changed

+97
-17
lines changed

4 files changed

+97
-17
lines changed

build/scripts/Benchmarking.fsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,18 @@ module Benchmarker =
2828
let pipelineName = "benchmark-pipeline"
2929
let indexName = IndexName.op_Implicit("benchmark-reports")
3030
let typeName = TypeName.op_Implicit("report")
31-
32-
type ProcessorName(isValueCreated:bool, value:string) =
33-
member val IsValueCreated=isValueCreated with get, set
34-
member val Value=value with get, set
35-
36-
type ChronometerFrequency(hertz:int) =
31+
32+
type Memory(gen0Collections:int, gen1Collections: int, gen2Collections: int, totalOperations:int64, bytesAllocatedPerOperation:int64) =
33+
member val Gen0Collections=gen0Collections with get, set
34+
member val Gen1Collections=gen1Collections with get, set
35+
member val Gen2Collections=gen2Collections with get, set
36+
member val TotalOperations=totalOperations with get, set
37+
member val BytesAllocatedPerOperation=bytesAllocatedPerOperation with get, set
38+
39+
type ChronometerFrequency(hertz:double) =
3740
member val Hertz=hertz with get, set
38-
39-
type HostEnvironmentInfo(benchmarkDotNetCaption:string, benchmarkDotNetVersion:string, osVersion: string, processorName:ProcessorName,
41+
42+
type HostEnvironmentInfo(benchmarkDotNetCaption:string, benchmarkDotNetVersion:string, osVersion: string, processorName:string,
4043
processorCount:int, runtimeVersion:string, architecture:string, hasAttachedDebugger:bool, hasRyuJit:bool,
4144
configuration:string, jitModules:string, dotnetCliVersion:string, chronometerFrequency:ChronometerFrequency,
4245
hardwareTimerKind:string) =
@@ -55,9 +58,10 @@ module Benchmarker =
5558
member val ChronometerFrequency=chronometerFrequency with get, set
5659
member val HardwareTimerKind=hardwareTimerKind with get, set
5760

58-
type ConfidenceInterval(mean: double, error:double, level:int, margin:double, lower:double, upper:double) =
61+
type ConfidenceInterval(n:int, mean: double, standardError:double, level:int, margin:double, lower:double, upper:double) =
62+
member val N=n with get, set
5963
member val Mean=mean with get, set
60-
member val Error=error with get, set
64+
member val StandardError=standardError with get, set
6165
member val Level=level with get, set
6266
member val Margin=margin with get, set
6367
member val Lower=lower with get, set
@@ -96,17 +100,20 @@ module Benchmarker =
96100
member val ConfidenceInterval=confidenceInterval with get, set
97101
member val Percentiles=percentiles with get, set
98102

99-
type Benchmark(displayInfo:string, namespyce:string, tipe:string, method:string, methodTitle:string, parameters:string, statistics:Statistics) =
103+
type Benchmark(displayInfo:string, namespyce:string, tipe:string, method:string, methodTitle:string, parameters:string,
104+
statistics:Statistics, memory:Memory) =
100105
member val DisplayInfo=displayInfo with get, set
101106
member val Namespace=namespyce with get, set
102107
member val Type=tipe with get, set
103108
member val Method=method with get, set
104109
member val MethodTitle=methodTitle with get, set
105110
member val Parameters=parameters with get, set
106111
member val Statistics=statistics with get, set
112+
member val Memory=memory with get, set
107113

108-
type Report(title: string, date:DateTime, commit:string, host:HostEnvironmentInfo, benchmarks:Benchmark list) =
114+
type Report(title: string, totalTime:TimeSpan, date:DateTime, commit:string, host:HostEnvironmentInfo, benchmarks:Benchmark list) =
109115
member val Title = title with get, set
116+
member val TotalTime = totalTime with get, set
110117
member val Date = date with get, set
111118
member val Commit = commit with get, set
112119
member val HostEnvironmentInfo = host with get, set
@@ -162,7 +169,7 @@ module Benchmarker =
162169
let commit = getSHA1 "." "HEAD"
163170

164171
let benchmarkJsonFiles =
165-
Directory.EnumerateFiles(benchmarkOutput.FullName, "*-brief.json", SearchOption.AllDirectories)
172+
Directory.EnumerateFiles(benchmarkOutput.FullName, "*-custom.json", SearchOption.AllDirectories)
166173
|> Seq.toList
167174

168175
let uri = new Uri(url)
Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,71 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using BenchmarkDotNet.Configs;
35
using BenchmarkDotNet.Environments;
46
using BenchmarkDotNet.Exporters.Json;
57
using BenchmarkDotNet.Jobs;
8+
using BenchmarkDotNet.Diagnosers;
9+
using BenchmarkDotNet.Loggers;
10+
using BenchmarkDotNet.Reports;
11+
using Newtonsoft.Json;
612

713
namespace Tests.Framework.Benchmarks
814
{
15+
#if NET46
16+
public class CustomJsonExporter : BenchmarkDotNet.Exporters.ExporterBase
17+
{
18+
protected override string FileExtension => "json";
19+
20+
protected override string FileNameSuffix => "-custom";
21+
22+
public override void ExportToLog(Summary summary, ILogger logger)
23+
{
24+
var environmentInfo = new
25+
{
26+
HostEnvironmentInfo.BenchmarkDotNetCaption,
27+
summary.HostEnvironmentInfo.BenchmarkDotNetVersion,
28+
OsVersion = summary.HostEnvironmentInfo.OsVersion.Value,
29+
ProcessorName = summary.HostEnvironmentInfo.ProcessorName.Value,
30+
summary.HostEnvironmentInfo.ProcessorCount,
31+
summary.HostEnvironmentInfo.RuntimeVersion,
32+
summary.HostEnvironmentInfo.Architecture,
33+
summary.HostEnvironmentInfo.HasAttachedDebugger,
34+
summary.HostEnvironmentInfo.HasRyuJit,
35+
summary.HostEnvironmentInfo.Configuration,
36+
summary.HostEnvironmentInfo.JitModules,
37+
DotNetCliVersion = summary.HostEnvironmentInfo.DotNetCliVersion.Value,
38+
summary.HostEnvironmentInfo.ChronometerFrequency,
39+
HardwareTimerKind = summary.HostEnvironmentInfo.HardwareTimerKind.ToString()
40+
};
41+
42+
var benchmarks = summary.Reports.Select(r =>
43+
{
44+
var data = new Dictionary<string, object>
45+
{
46+
{ "DisplayInfo", r.Benchmark.DisplayInfo },
47+
{ "Namespace", r.Benchmark.Target.Type.Namespace },
48+
{ "Type", r.Benchmark.Target.Type.Name },
49+
{ "Method", r.Benchmark.Target.Method.Name },
50+
{ "MethodTitle", r.Benchmark.Target.MethodDisplayInfo },
51+
{ "Parameters", r.Benchmark.Parameters.PrintInfo },
52+
{ "Statistics", r.ResultStatistics },
53+
{ "Memory", r.GcStats }
54+
};
55+
56+
return data;
57+
});
58+
59+
logger.WriteLine(JsonConvert.SerializeObject(new Dictionary<string, object>
60+
{
61+
{ "Title", summary.Title },
62+
{ "TotalTime", summary.TotalTime },
63+
{ "HostEnvironmentInfo", environmentInfo },
64+
{ "Benchmarks", benchmarks }
65+
}));
66+
}
67+
}
68+
#endif
969
public class BenchmarkConfigAttribute : Attribute, IConfigSource
1070
{
1171
public IConfig Config { get; }
@@ -14,10 +74,17 @@ public BenchmarkConfigAttribute(int runCount = 1)
1474
{
1575
var jobs = new[] {
1676
Job.Dry.With(Runtime.Core).With(Jit.RyuJit).WithTargetCount(runCount),
17-
Job.Dry.With(Runtime.Clr).With(Jit.RyuJit).WithTargetCount(runCount),
77+
Job.Dry.With(Runtime.Clr).With(Jit.RyuJit).WithTargetCount(runCount),
1878
Job.Dry.With(Runtime.Clr).With(Jit.LegacyJit).WithTargetCount(runCount)
1979
};
20-
Config = ManualConfig.CreateEmpty().With(jobs).With(JsonExporter.Brief);
80+
#if !NET46
81+
Config = DefaultConfig.Instance.With(jobs).With(JsonExporter.Brief);
82+
#else
83+
Config = DefaultConfig.Instance
84+
.With(jobs)
85+
.With(new CustomJsonExporter())
86+
.With(MemoryDiagnoser.Default);
87+
#endif
2188
}
2289
}
2390
}

src/Tests/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static void Main(string[] args)
9191
else if (args[0].Equals("Benchmark", StringComparison.OrdinalIgnoreCase))
9292
{
9393
Console.WriteLine("Running Benchmarking.");
94-
if (args[1].Equals("non-interactive", StringComparison.OrdinalIgnoreCase))
94+
if (args.Count() > 1 && args[1].Equals("non-interactive", StringComparison.OrdinalIgnoreCase))
9595
{
9696
Console.WriteLine("Running as Non-Interactive.");
9797
foreach (var benchmarkType in GetBenchmarkTypes())

src/Tests/Tests.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
<PackageReference Include="FluentAssertions" Version="4.19.2" />
2121
<PackageReference Include="xunit" Version="2.3.0-beta1-build3642" />
2222
<PackageReference Include="SemanticVersioning" Version="0.7.6" />
23-
<PackageReference Include="BenchMarkDotNet" Version="0.10.0" />
2423
<PackageReference Include="DiffPlex" Version="1.4.1" />
2524
<PackageReference Include="System.Reactive" Version="3.1.1" />
25+
2626
<!-- TODO only for Desktop CLR? -->
2727
<PackageReference Include="System.Buffers" Version="4.3.0" />
2828
<!-- TODO update -->
@@ -35,6 +35,12 @@
3535
<PackageReference Include="System.Net.Http" Version="4.3.0" />
3636
<PackageReference Include="System.Diagnostics.FileVersionInfo" Version="4.3.0" />
3737
</ItemGroup>
38+
<ItemGroup Condition="'$(TargetFramework)'!='net45'">
39+
<PackageReference Include="BenchMarkDotNet" Version="0.10.8" />
40+
</ItemGroup>
41+
<ItemGroup Condition="'$(TargetFramework)'=='net45'">
42+
<PackageReference Include="BenchMarkDotNet" Version="0.10.0" />
43+
</ItemGroup>
3844
<ItemGroup>
3945
<EmbeddedResource Include="Document\Single\Index\Attachment_Test_Document.pdf" />
4046
</ItemGroup>

0 commit comments

Comments
 (0)