Skip to content

Commit da6cac4

Browse files
committed
Use global:: prefix for setup, cleanup, and async benchmarks.
Fix missing prefixes. Update Params and Arguments. Remove ValidateNamingConflicts and test more name conflicts.
1 parent c2b6dd7 commit da6cac4

File tree

6 files changed

+62
-52
lines changed

6 files changed

+62
-52
lines changed

src/BenchmarkDotNet/Code/CodeGenerator.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ internal static string Generate(BuildPartition buildPartition)
4949
.Replace("$IterationSetupMethodName$", provider.IterationSetupMethodName)
5050
.Replace("$IterationCleanupMethodName$", provider.IterationCleanupMethodName)
5151
.Replace("$JobSetDefinition$", GetJobsSetDefinition(benchmark))
52-
.Replace("$ParamsInitializer$", GetParamsInitializer(benchmark))
5352
.Replace("$ParamsContent$", GetParamsContent(benchmark))
5453
.Replace("$ArgumentsDefinition$", GetArgumentsDefinition(benchmark))
5554
.Replace("$DeclareArgumentFields$", GetDeclareArgumentFields(benchmark))
56-
.Replace("$InitializeArgumentFields$", GetInitializeArgumentFields(benchmark)).Replace("$LoadArguments$", GetLoadArguments(benchmark))
55+
.Replace("$InitializeArgumentFields$", GetInitializeArgumentFields(benchmark))
56+
.Replace("$LoadArguments$", GetLoadArguments(benchmark))
5757
.Replace("$PassArguments$", passArguments)
5858
.Replace("$EngineFactoryType$", GetEngineFactoryTypeName(benchmark))
5959
.Replace("$MeasureExtraStats$", buildInfo.Config.HasExtraStatsDiagnoser() ? "true" : "false")
@@ -159,21 +159,14 @@ private static DeclarationsProvider GetDeclarationsProvider(Descriptor descripto
159159
return new SyncDeclarationsProvider(descriptor);
160160
}
161161

162-
private static string GetParamsInitializer(BenchmarkCase benchmarkCase)
163-
=> string.Join(
164-
", ",
165-
benchmarkCase.Parameters.Items
166-
.Where(parameter => !parameter.IsArgument && !parameter.IsStatic)
167-
.Select(parameter => $"{parameter.Name} = default"));
168-
169162
// internal for tests
170163

171164
internal static string GetParamsContent(BenchmarkCase benchmarkCase)
172165
=> string.Join(
173166
string.Empty,
174167
benchmarkCase.Parameters.Items
175168
.Where(parameter => !parameter.IsArgument)
176-
.Select(parameter => $"{(parameter.IsStatic ? "" : "instance.")}{parameter.Name} = {parameter.ToSourceCode()};"));
169+
.Select(parameter => $"{(parameter.IsStatic ? parameter.Definition.ParameterType.GetCorrectCSharpTypeName() : "base")}.{parameter.Name} = {parameter.ToSourceCode()};"));
177170

178171
private static string GetArgumentsDefinition(BenchmarkCase benchmarkCase)
179172
=> string.Join(
@@ -191,13 +184,13 @@ private static string GetInitializeArgumentFields(BenchmarkCase benchmarkCase)
191184
=> string.Join(
192185
Environment.NewLine,
193186
benchmarkCase.Descriptor.WorkloadMethod.GetParameters()
194-
.Select((parameter, index) => $"__argField{index} = {benchmarkCase.Parameters.GetArgument(parameter.Name).ToSourceCode()};")); // we init the fields in ctor to provoke all possible allocations and overhead of other type
187+
.Select((parameter, index) => $"this.__argField{index} = {benchmarkCase.Parameters.GetArgument(parameter.Name).ToSourceCode()};")); // we init the fields in ctor to provoke all possible allocations and overhead of other type
195188

196189
private static string GetLoadArguments(BenchmarkCase benchmarkCase)
197190
=> string.Join(
198191
Environment.NewLine,
199192
benchmarkCase.Descriptor.WorkloadMethod.GetParameters()
200-
.Select((parameter, index) => $"{(parameter.ParameterType.IsByRef ? "ref" : string.Empty)} {parameter.ParameterType.GetCorrectCSharpTypeName()} arg{index} = {(parameter.ParameterType.IsByRef ? "ref" : string.Empty)} __argField{index};"));
193+
.Select((parameter, index) => $"{(parameter.ParameterType.IsByRef ? "ref" : string.Empty)} {parameter.ParameterType.GetCorrectCSharpTypeName()} arg{index} = {(parameter.ParameterType.IsByRef ? "ref" : string.Empty)} this.__argField{index};"));
201194

202195
private static string GetPassArguments(BenchmarkCase benchmarkCase)
203196
=> string.Join(

src/BenchmarkDotNet/Code/DeclarationsProvider.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ internal abstract class DeclarationsProvider
2828

2929
public abstract string GetWorkloadMethodCall(string passArguments);
3030

31-
protected string WorkloadMethodPrefix => Descriptor.WorkloadMethod.IsStatic ? Descriptor.WorkloadMethod.DeclaringType.GetCorrectCSharpTypeName() : "base";
31+
protected static string GetMethodPrefix(MethodInfo method)
32+
=> method.IsStatic ? method.DeclaringType.GetCorrectCSharpTypeName() : "base";
3233

3334
private string GetMethodName(MethodInfo method)
3435
{
@@ -43,22 +44,22 @@ private string GetMethodName(MethodInfo method)
4344
(method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>) ||
4445
method.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))))
4546
{
46-
return $"() => BenchmarkDotNet.Helpers.AwaitHelper.GetResult({method.Name}())";
47+
return $"() => global::BenchmarkDotNet.Helpers.AwaitHelper.GetResult({GetMethodPrefix(Descriptor.WorkloadMethod)}.{method.Name}())";
4748
}
4849

49-
return method.Name;
50+
return $"{GetMethodPrefix(Descriptor.WorkloadMethod)}.{method.Name}";
5051
}
5152
}
5253

5354
internal class SyncDeclarationsProvider(Descriptor descriptor) : DeclarationsProvider(descriptor)
5455
{
5556
public override string GetWorkloadMethodCall(string passArguments)
56-
=> $"{WorkloadMethodPrefix}.{Descriptor.WorkloadMethod.Name}({passArguments})";
57+
=> $"{GetMethodPrefix(Descriptor.WorkloadMethod)}.{Descriptor.WorkloadMethod.Name}({passArguments})";
5758
}
5859

5960
internal class AsyncDeclarationsProvider(Descriptor descriptor) : DeclarationsProvider(descriptor)
6061
{
6162
public override string GetWorkloadMethodCall(string passArguments)
62-
=> $"BenchmarkDotNet.Helpers.AwaitHelper.GetResult({WorkloadMethodPrefix}.{Descriptor.WorkloadMethod.Name}({passArguments}))";
63+
=> $"global::BenchmarkDotNet.Helpers.AwaitHelper.GetResult({GetMethodPrefix(Descriptor.WorkloadMethod)}.{Descriptor.WorkloadMethod.Name}({passArguments}))";
6364
}
6465
}

src/BenchmarkDotNet/Templates/BenchmarkProgram.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ $AdditionalLogic$
55
// this file must not be importing any namespaces
66
// we should use full names everywhere to avoid any potential naming conflicts, example: #1007, #778
77

8+
#if !NET7_0_OR_GREATER
9+
namespace System.Diagnostics.CodeAnalysis
10+
{
11+
/// <summary>
12+
/// Specifies that this constructor sets all required members for the current type,
13+
/// and callers do not need to set any required members themselves.
14+
/// </summary>
15+
[global::System.AttributeUsage(global::System.AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
16+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
17+
internal sealed class SetsRequiredMembersAttribute : global::System.Attribute
18+
{
19+
}
20+
}
21+
#endif
22+
823
// the namespace name must be in sync with WindowsDisassembler.BuildArguments
924
namespace BenchmarkDotNet.Autogenerated
1025
{

src/BenchmarkDotNet/Templates/BenchmarkType.txt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
{
44
public static void Run(global::BenchmarkDotNet.Engines.IHost host, global::System.String benchmarkName, global::BenchmarkDotNet.Diagnosers.RunMode diagnoserRunMode)
55
{
6-
global::BenchmarkDotNet.Autogenerated.Runnable_$ID$ instance = new global::BenchmarkDotNet.Autogenerated.Runnable_$ID$ { $ParamsInitializer$ }; // do NOT change name "instance" (used in SmartParamameter)
7-
$ParamsContent$
6+
global::BenchmarkDotNet.Autogenerated.Runnable_$ID$ instance = new global::BenchmarkDotNet.Autogenerated.Runnable_$ID$(); // do NOT change name "instance" (used in SmartParamameter)
87

98
host.WriteLine();
109
foreach (global::System.String infoLine in global::BenchmarkDotNet.Environments.BenchmarkEnvironmentInfo.GetCurrent().ToFormattedString())
@@ -65,13 +64,15 @@
6564
compositeInProcessDiagnoserHandler.Handle(global::BenchmarkDotNet.Engines.BenchmarkSignal.AfterEngine);
6665
}
6766

67+
[global::System.Diagnostics.CodeAnalysis.SetsRequiredMembers]
6868
public Runnable_$ID$()
6969
{
7070
this.globalSetupAction = $GlobalSetupMethodName$;
7171
this.globalCleanupAction = $GlobalCleanupMethodName$;
7272
this.iterationSetupAction = $IterationSetupMethodName$;
7373
this.iterationCleanupAction = $IterationCleanupMethodName$;
7474
$InitializeArgumentFields$
75+
$ParamsContent$
7576
}
7677

7778
private global::System.Action globalSetupAction;
@@ -101,11 +102,11 @@
101102
}
102103

103104
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
104-
private void __Overhead($ArgumentsDefinition$) // __ is to avoid possible name conflict
105+
private void __Overhead($ArgumentsDefinition$)
105106
{
106107
}
107108

108-
[global::System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
109+
[global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
109110
private void OverheadActionUnroll(global::System.Int64 invokeCount)
110111
{
111112
$LoadArguments$
@@ -115,7 +116,7 @@
115116
}
116117
}
117118

118-
[global::System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
119+
[global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
119120
private void OverheadActionNoUnroll(global::System.Int64 invokeCount)
120121
{
121122
$LoadArguments$
@@ -125,7 +126,7 @@
125126
}
126127
}
127128

128-
[global::System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
129+
[global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
129130
private void WorkloadActionUnroll(global::System.Int64 invokeCount)
130131
{
131132
$LoadArguments$
@@ -135,7 +136,7 @@
135136
}
136137
}
137138

138-
[global::System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
139+
[global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
139140
private void WorkloadActionNoUnroll(global::System.Int64 invokeCount)
140141
{
141142
$LoadArguments$

src/BenchmarkDotNet/Validators/CompilationValidator.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ private CompilationValidator() { }
2525

2626
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)
2727
=> ValidateCSharpNaming(validationParameters.Benchmarks)
28-
.Union(ValidateNamingConflicts(validationParameters.Benchmarks))
2928
.Union(ValidateClassModifiers((validationParameters.Benchmarks))
3029
.Union(ValidateAccessModifiers(validationParameters.Benchmarks))
3130
.Union(ValidateBindingModifiers(validationParameters.Benchmarks))
@@ -71,16 +70,6 @@ private static IEnumerable<ValidationError> ValidateCSharpNaming(IEnumerable<Ben
7170
benchmark
7271
));
7372

74-
private static IEnumerable<ValidationError> ValidateNamingConflicts(IEnumerable<BenchmarkCase> benchmarks)
75-
=> benchmarks
76-
.Select(benchmark => benchmark.Descriptor.Type)
77-
.Distinct()
78-
.Where(type => type.GetAllMethods().Any(method => IsUsingNameUsedInternallyByOurTemplate(method.Name)))
79-
.Select(benchmark
80-
=> new ValidationError(
81-
true,
82-
"Using \"__Overhead\" for method name is prohibited. We are using it internally in our templates. Please rename your method"));
83-
8473
private static IEnumerable<ValidationError> ValidateAccessModifiers(IEnumerable<BenchmarkCase> benchmarks)
8574
=> benchmarks.Where(x => x.Descriptor.Type.IsGenericType
8675
&& HasPrivateGenericArguments(x.Descriptor.Type))
@@ -113,9 +102,6 @@ private static bool IsValidCSharpIdentifier(string identifier) // F# allows to u
113102
&& identifier.Skip(1).All(character => char.IsLetterOrDigit(character) || character == Underscore)
114103
&& !CsharpKeywords.Contains(identifier);
115104

116-
private static bool IsUsingNameUsedInternallyByOurTemplate(string identifier)
117-
=> identifier == "__Overhead";
118-
119105
private static bool HasPrivateGenericArguments(Type type) => type.GetGenericArguments().Any(a => !(a.IsPublic || a.IsNestedPublic));
120106

121107
// source: https://stackoverflow.com/a/19562316

tests/BenchmarkDotNet.IntegrationTests/ConflictingNamesTests.cs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,42 @@
22
using Xunit;
33
using Xunit.Abstractions;
44

5-
namespace BenchmarkDotNet.IntegrationTests
5+
namespace BenchmarkDotNet.IntegrationTests;
6+
7+
public class ConflictingNamesTests(ITestOutputHelper output) : BenchmarkTestExecutor(output)
68
{
7-
public class ConflictingNamesTests : BenchmarkTestExecutor
9+
[Fact]
10+
public void BenchmarkMethodsCanUseTemplateNames() => CanExecute<WithNamesUsedByTemplate>();
11+
12+
public class WithNamesUsedByTemplate
813
{
9-
public ConflictingNamesTests(ITestOutputHelper output) : base(output) { }
14+
[Params(1)]
15+
public int OverheadActionUnroll { get; set; }
16+
17+
[Benchmark]
18+
[Arguments(2)]
19+
public void System(int OverheadActionNoUnroll)
20+
{
1021

11-
[Fact]
12-
public void BenchmarkMethodsCanUseTemplateNames() => CanExecute<WithNamesUsedByTemplate>();
22+
}
1323

14-
public class WithNamesUsedByTemplate
24+
[Benchmark]
25+
public void BenchmarkDotNet()
1526
{
16-
[Benchmark]
17-
public void System()
18-
{
1927

20-
}
28+
}
2129

22-
[Benchmark]
23-
public void BenchmarkDotNet()
24-
{
30+
[Benchmark]
31+
public void __Overhead()
32+
{
33+
34+
}
35+
36+
[Benchmark]
37+
[Arguments(3)]
38+
public void WorkloadActionUnroll(int WorkloadActionNoUnroll)
39+
{
2540

26-
}
2741
}
2842
}
2943
}

0 commit comments

Comments
 (0)