Sample: IntroArgumentsSource
In case you want to use a lot of values, you should use
[ArgumentsSource]
.
You can mark one or several fields or properties in your class by the
[ArgumentsSource]
attribute.
In this attribute, you have to specify the name of public method/property which is going to provide the values
(something that implements IEnumerable
).
The source must be within benchmarked type!
Source code
using System;
using System.Collections.Generic;
using System.Threading;
using BenchmarkDotNet.Attributes;
namespace BenchmarkDotNet.Samples
{
public class IntroArgumentsSource
{
[Benchmark]
[ArgumentsSource(nameof(Numbers))]
public double ManyArguments(double x, double y) => Math.Pow(x, y);
public IEnumerable<object[]> Numbers() // for multiple arguments it's an IEnumerable of array of objects (object[])
{
yield return new object[] { 1.0, 1.0 };
yield return new object[] { 2.0, 2.0 };
yield return new object[] { 4.0, 4.0 };
yield return new object[] { 10.0, 10.0 };
}
[Benchmark]
[ArgumentsSource(nameof(TimeSpans))]
public void SingleArgument(TimeSpan time) => Thread.Sleep(time);
public IEnumerable<object> TimeSpans() // for single argument it's an IEnumerable of objects (object)
{
yield return TimeSpan.FromMilliseconds(10);
yield return TimeSpan.FromMilliseconds(100);
}
}
}
Output
| Method | x | y | Mean | Error | StdDev |
|------- |--- |--- |----------:|----------:|----------:|
| Pow | 1 | 1 | 9.360 ns | 0.0190 ns | 0.0149 ns |
| Pow | 2 | 2 | 40.624 ns | 0.3413 ns | 0.3192 ns |
| Pow | 4 | 4 | 40.537 ns | 0.0560 ns | 0.0524 ns |
| Pow | 10 | 10 | 40.395 ns | 0.3274 ns | 0.3063 ns |
Another example
If the values are complex types you need to override ToString
method to change the display names used in the results.
[DryJob]
public class WithNonPrimitiveArgumentsSource
{
[Benchmark]
[ArgumentsSource(nameof(NonPrimitive))]
public void Simple(SomeClass someClass, SomeStruct someStruct)
{
for (int i = 0; i < someStruct.RangeEnd; i++)
Console.WriteLine($"// array.Values[{i}] = {someClass.Values[i]}");
}
public IEnumerable<object[]> NonPrimitive()
{
yield return new object[] { new SomeClass(Enumerable.Range(0, 10).ToArray()), new SomeStruct(10) };
yield return new object[] { new SomeClass(Enumerable.Range(0, 15).ToArray()), new SomeStruct(15) };
}
public class SomeClass
{
public SomeClass(int[] initialValues) => Values = initialValues.Select(val => val * 2).ToArray();
public int[] Values { get; }
public override string ToString() => $"{Values.Length} items";
}
public struct SomeStruct
{
public SomeStruct(int rangeEnd) => RangeEnd = rangeEnd;
public int RangeEnd { get; }
public override string ToString() => $"{RangeEnd}";
}
}
| Method | someClass | someStruct | Mean | Error |
|------- |---------- |----------- |---------:|------:|
| Simple | 10 items | 10 | 887.2 us | NA |
| Simple | 15 items | 15 | 963.1 us | NA |
Links
- Parameterization
- The permanent link to this sample: BenchmarkDotNet.Samples.IntroArgumentsSource