Skip to content

Commit 4abbb1f

Browse files
committed
Removed Consumer from benchmark actions.
Overhead always returns `void`.
1 parent 95ad39f commit 4abbb1f

File tree

14 files changed

+99
-919
lines changed

14 files changed

+99
-919
lines changed

src/BenchmarkDotNet/Code/CodeGenerator.cs

-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,10 @@ internal static string Generate(BuildPartition buildPartition)
4747
.Replace("$WorkloadTypeName$", provider.WorkloadTypeName)
4848
.Replace("$WorkloadMethodReturnType$", provider.WorkloadMethodReturnTypeName)
4949
.Replace("$WorkloadMethodReturnTypeModifiers$", provider.WorkloadMethodReturnTypeModifiers)
50-
.Replace("$OverheadMethodReturnTypeName$", provider.OverheadMethodReturnTypeName)
5150
.Replace("$GlobalSetupMethodName$", provider.GlobalSetupMethodName)
5251
.Replace("$GlobalCleanupMethodName$", provider.GlobalCleanupMethodName)
5352
.Replace("$IterationSetupMethodName$", provider.IterationSetupMethodName)
5453
.Replace("$IterationCleanupMethodName$", provider.IterationCleanupMethodName)
55-
.Replace("$OverheadImplementation$", provider.OverheadImplementation)
56-
.Replace("$ConsumeField$", provider.ConsumeField)
5754
.Replace("$JobSetDefinition$", GetJobsSetDefinition(benchmark))
5855
.Replace("$ParamsContent$", GetParamsContent(benchmark))
5956
.Replace("$ArgumentsDefinition$", GetArgumentsDefinition(benchmark))

src/BenchmarkDotNet/Code/DeclarationsProvider.cs

+1-52
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ internal abstract class DeclarationsProvider
4040

4141
public virtual string GetWorkloadMethodCall(string passArguments) => $"{Descriptor.WorkloadMethod.Name}({passArguments})";
4242

43-
public virtual string ConsumeField => null;
44-
45-
protected abstract Type OverheadMethodReturnType { get; }
46-
47-
public string OverheadMethodReturnTypeName => OverheadMethodReturnType.GetCorrectCSharpTypeName();
48-
49-
public abstract string OverheadImplementation { get; }
50-
5143
private string GetMethodName(MethodInfo method)
5244
{
5345
if (method == null)
@@ -73,62 +65,21 @@ internal class VoidDeclarationsProvider : DeclarationsProvider
7365
public VoidDeclarationsProvider(Descriptor descriptor) : base(descriptor) { }
7466

7567
public override string ReturnsDefinition => "RETURNS_VOID";
76-
77-
protected override Type OverheadMethodReturnType => typeof(void);
78-
79-
public override string OverheadImplementation => string.Empty;
8068
}
8169

8270
internal class NonVoidDeclarationsProvider : DeclarationsProvider
8371
{
8472
public NonVoidDeclarationsProvider(Descriptor descriptor) : base(descriptor) { }
8573

86-
public override string ConsumeField
87-
=> !Consumer.IsConsumable(WorkloadMethodReturnType) && Consumer.HasConsumableField(WorkloadMethodReturnType, out var field)
88-
? $".{field.Name}"
89-
: null;
90-
91-
protected override Type OverheadMethodReturnType
92-
=> Consumer.IsConsumable(WorkloadMethodReturnType)
93-
? WorkloadMethodReturnType
94-
: (Consumer.HasConsumableField(WorkloadMethodReturnType, out var field)
95-
? field.FieldType
96-
: typeof(int)); // we return this simple type because creating bigger ValueType could take longer than benchmarked method itself
97-
98-
public override string OverheadImplementation
99-
{
100-
get
101-
{
102-
string value;
103-
var type = OverheadMethodReturnType;
104-
if (type.GetTypeInfo().IsPrimitive)
105-
value = $"default({type.GetCorrectCSharpTypeName()})";
106-
else if (type.GetTypeInfo().IsClass || type.GetTypeInfo().IsInterface)
107-
value = "null";
108-
else
109-
value = SourceCodeHelper.ToSourceCode(Activator.CreateInstance(type)) + ";";
110-
return $"return {value};";
111-
}
112-
}
113-
114-
public override string ReturnsDefinition
115-
=> Consumer.IsConsumable(WorkloadMethodReturnType) || Consumer.HasConsumableField(WorkloadMethodReturnType, out _)
116-
? "RETURNS_CONSUMABLE"
117-
: "RETURNS_NON_CONSUMABLE_STRUCT";
74+
public override string ReturnsDefinition => "RETURNS_NON_VOID";
11875
}
11976

12077
internal class ByRefDeclarationsProvider : NonVoidDeclarationsProvider
12178
{
12279
public ByRefDeclarationsProvider(Descriptor descriptor) : base(descriptor) { }
12380

124-
protected override Type OverheadMethodReturnType => typeof(IntPtr);
125-
12681
public override string WorkloadMethodReturnTypeName => base.WorkloadMethodReturnTypeName.Replace("&", string.Empty);
12782

128-
public override string ConsumeField => null;
129-
130-
public override string OverheadImplementation => $"return default(System.{nameof(IntPtr)});";
131-
13283
public override string ReturnsDefinition => "RETURNS_BYREF";
13384

13485
public override string WorkloadMethodReturnTypeModifiers => "ref";
@@ -138,8 +89,6 @@ internal class ByReadOnlyRefDeclarationsProvider : ByRefDeclarationsProvider
13889
{
13990
public ByReadOnlyRefDeclarationsProvider(Descriptor descriptor) : base(descriptor) { }
14091

141-
public override string ReturnsDefinition => "RETURNS_BYREF_READONLY";
142-
14392
public override string WorkloadMethodReturnTypeModifiers => "ref readonly";
14493
}
14594

src/BenchmarkDotNet/Engines/Consumer.cs

-33
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Reflection;
52
using System.Runtime.CompilerServices;
63
using System.Threading;
74
using JetBrains.Annotations;
@@ -11,13 +8,6 @@ namespace BenchmarkDotNet.Engines
118
{
129
public class Consumer
1310
{
14-
private static readonly HashSet<Type> SupportedTypes
15-
= new HashSet<Type>(
16-
typeof(Consumer).GetTypeInfo()
17-
.DeclaredFields
18-
.Where(field => !field.IsStatic) // exclude this HashSet itself
19-
.Select(field => field.FieldType));
20-
2111
#pragma warning disable IDE0052 // Remove unread private members
2212
private volatile byte byteHolder;
2313
private volatile sbyte sbyteHolder;
@@ -153,28 +143,5 @@ public void Consume<T>(in T value)
153143
else
154144
DeadCodeEliminationHelper.KeepAliveWithoutBoxingReadonly(value); // non-primitive and nullable value types
155145
}
156-
157-
internal static bool IsConsumable(Type type)
158-
=> SupportedTypes.Contains(type) || type.GetTypeInfo().IsClass || type.GetTypeInfo().IsInterface;
159-
160-
internal static bool HasConsumableField(Type type, out FieldInfo? consumableField)
161-
{
162-
var typeInfo = type.GetTypeInfo();
163-
164-
if (typeInfo.IsEnum)
165-
{
166-
// Enums are tricky bastards which report "value__" field, which is public for reflection, but inaccessible via C#
167-
consumableField = null;
168-
return false;
169-
}
170-
171-
var publicInstanceFields = typeInfo.DeclaredFields
172-
.Where(field => field.IsPublic && !field.IsStatic)
173-
.ToArray();
174-
175-
consumableField = publicInstanceFields.FirstOrDefault(field => IsConsumable(field.FieldType));
176-
177-
return consumableField != null;
178-
}
179146
}
180147
}

src/BenchmarkDotNet/Helpers/Reflection.Emit/IlGeneratorDefaultValueExtensions.cs

+8-21
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,20 @@ public static LocalBuilder DeclareOptionalLocalForReturnDefault(this ILGenerator
1212
: null;
1313
}
1414

15-
public static void EmitSetLocalToDefault(this ILGenerator ilBuilder, LocalBuilder local)
16-
{
17-
var resultType = local.LocalType;
18-
switch (resultType)
19-
{
20-
case Type t when t == typeof(void):
21-
break;
22-
case Type t when t.IsClass || t.IsInterface:
23-
ilBuilder.Emit(OpCodes.Ldnull);
24-
ilBuilder.EmitStloc(local);
25-
break;
26-
case Type t when t.UseInitObjForInitLocal():
27-
EmitInitObj(ilBuilder, resultType, local);
28-
break;
29-
default:
30-
EmitLoadDefaultPrimitive(ilBuilder, resultType);
31-
ilBuilder.EmitStloc(local);
32-
break;
33-
}
34-
}
35-
3615
public static void EmitReturnDefault(this ILGenerator ilBuilder, Type resultType, LocalBuilder optionalLocalForInitobj)
3716
{
3817
switch (resultType)
3918
{
4019
case Type t when t == typeof(void):
4120
break;
21+
case Type t when t.IsPointer: // Type.IsClass returns true for pointers, so we have to check for pointer type first.
22+
/*
23+
IL_0000: ldc.i4.0
24+
IL_0001: conv.u
25+
*/
26+
ilBuilder.Emit(OpCodes.Ldc_I4_0);
27+
ilBuilder.Emit(OpCodes.Conv_U);
28+
break;
4229
case Type t when t.IsClass || t.IsInterface:
4330
ilBuilder.Emit(OpCodes.Ldnull);
4431
break;

0 commit comments

Comments
 (0)