Skip to content

Commit ea0468f

Browse files
authored
Support IEnumerable as benchmark argument (#1228)
* implement tests * fix: cast to parameter/argument type, not to argument value type
1 parent 88ea5a8 commit ea0468f

File tree

6 files changed

+39
-9
lines changed

6 files changed

+39
-9
lines changed
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
namespace BenchmarkDotNet.Parameters
1+
using System;
2+
3+
namespace BenchmarkDotNet.Parameters
24
{
35
public class ParameterDefinition
46
{
57
public string Name { get; }
68
public bool IsStatic { get; }
79
public object[] Values { get; }
810
public bool IsArgument { get; }
11+
public Type ParameterType { get; }
912

10-
public ParameterDefinition(string name, bool isStatic, object[] values, bool isArgument)
13+
public ParameterDefinition(string name, bool isStatic, object[] values, bool isArgument, Type parameterType)
1114
{
1215
Name = name;
1316
IsStatic = isStatic;
1417
Values = values;
1518
IsArgument = isArgument;
19+
ParameterType = parameterType;
1620
}
1721
}
1822
}

src/BenchmarkDotNet/Parameters/SmartParamBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public SmartArgument(ParameterDefinition[] parameterDefinitions, object value, M
8383

8484
public string ToSourceCode()
8585
{
86-
string cast = $"({Value.GetType().GetCorrectCSharpTypeName()})"; // it's an object so we need to cast it to the right type
86+
string cast = $"({parameterDefinitions[argumentIndex].ParameterType.GetCorrectCSharpTypeName()})"; // it's an object so we need to cast it to the right type
8787

8888
string callPostfix = source is PropertyInfo ? string.Empty : "()";
8989

src/BenchmarkDotNet/Running/BenchmarkConverter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ IEnumerable<ParameterDefinition> GetDefinitions<TAttribute>(Func<TAttribute, Typ
174174
member.Name,
175175
member.IsStatic,
176176
getValidValues(member.Attribute, member.ParameterType),
177-
false));
177+
false,
178+
member.ParameterType));
178179
}
179180

180181
var paramsDefinitions = GetDefinitions<ParamsAttribute>((attribute, parameterType) => GetValidValues(attribute.Values, parameterType));
@@ -195,7 +196,7 @@ IEnumerable<ParameterDefinition> GetDefinitions<TAttribute>(Func<TAttribute, Typ
195196
private static IEnumerable<ParameterInstances> GetArgumentsDefinitions(MethodInfo benchmark, Type target)
196197
{
197198
var parameterDefinitions = benchmark.GetParameters()
198-
.Select(parameter => new ParameterDefinition(parameter.Name, false, Array.Empty<object>(), true))
199+
.Select(parameter => new ParameterDefinition(parameter.Name, false, Array.Empty<object>(), true, parameter.ParameterType))
199200
.ToArray();
200201

201202
if (parameterDefinitions.IsEmpty())

tests/BenchmarkDotNet.IntegrationTests/ArgumentsTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,31 @@ public void AcceptingArray(int[] array)
171171
}
172172
}
173173

174+
[Theory, MemberData(nameof(GetToolchains))]
175+
public void IEnumerableCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithIEnumerable>(toolchain);
176+
177+
public class WithIEnumerable
178+
{
179+
private static IEnumerable<int> Iterator() { yield return 1; }
180+
181+
public IEnumerable<object[]> Sources()
182+
{
183+
yield return new object[] { "Empty", Enumerable.Empty<int>() };
184+
yield return new object[] { "Range", Enumerable.Range(0, 10) };
185+
yield return new object[] { "List", new List<int>() { 1, 2, 3 } };
186+
yield return new object[] { "int[]", new int[] { 1, 2, 3 } };
187+
yield return new object[] { "int[].Select", new int[] { 1, 2, 3 }.Select(i => i) };
188+
yield return new object[] { "int[].Select.Where", new int[] { 1, 2, 3 }.Select(i => i).Where(i => i % 2 == 0) };
189+
yield return new object[] { "Iterator", Iterator() };
190+
yield return new object[] { "Iterator.Select", Iterator().Select(i => i) };
191+
yield return new object[] { "Iterator.Select.Where", Iterator().Select(i => i).Where(i => i % 2 == 0) };
192+
}
193+
194+
[Benchmark]
195+
[ArgumentsSource(nameof(Sources))]
196+
public void Any(string name, IEnumerable<int> source) => source.Any();
197+
}
198+
174199
[Theory, MemberData(nameof(GetToolchains))]
175200
public void JaggedArrayCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithJaggedArray>(toolchain);
176201

tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public void BasicComparisionTest()
1212
{
1313
var comparer = ParameterComparer.Instance;
1414

15-
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false);
15+
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false, parameterType: null);
1616
var originalData = new[]
1717
{
1818
new ParameterInstances(new[]
@@ -40,7 +40,7 @@ public void MultiParameterComparisionTest()
4040
{
4141
var comparer = ParameterComparer.Instance;
4242

43-
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false);
43+
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false, parameterType: null);
4444
var originalData = new[]
4545
{
4646
new ParameterInstances(new[]
@@ -94,7 +94,7 @@ public void AlphaNumericComparisionTest()
9494
{
9595
var comparer = ParameterComparer.Instance;
9696

97-
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false);
97+
var sharedDefinition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false, parameterType: null);
9898
var originalData = new[]
9999
{
100100
new ParameterInstances(new[]

tests/BenchmarkDotNet.Tests/ParameterInstanceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace BenchmarkDotNet.Tests
77
{
88
public class ParameterInstanceTests
99
{
10-
private static readonly ParameterDefinition definition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false);
10+
private static readonly ParameterDefinition definition = new ParameterDefinition("Testing", isStatic: false, values: Array.Empty<object>(), isArgument: false, parameterType: null);
1111

1212
[Theory]
1313
[InlineData(5)]

0 commit comments

Comments
 (0)