-
-
Notifications
You must be signed in to change notification settings - Fork 965
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Added [ParamsAllValues] * #658: restore lost ParamsAllValues attribute * #658: fix sample * #658: remove attribute's duplicate * #658: add tests and validator for ParamsAllValues * #658: update docs * #658: remove integration tests * #658: refactor ParamsAllValues validator * #658: update docs
- Loading branch information
1 parent
c3b6095
commit 922dfff
Showing
16 changed files
with
439 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
uid: BenchmarkDotNet.Samples.IntroParamsAllValues | ||
--- | ||
|
||
## Sample: IntroParamsAllValues | ||
|
||
If you want to use all possible values of an `enum` or another type with a small number of values, you can use the [`[ParamsAllValues]`](xref:BenchmarkDotNet.Attributes.ParamsAllValuesAttribute) attribute, instead of listing all the values by hand. The types supported by the attribute are: | ||
|
||
* `bool` | ||
* any `enum` that is not marked with `[Flags]` | ||
* `Nullable<T>`, where `T` is an enum or boolean | ||
|
||
### Source code | ||
|
||
[!code-csharp[IntroParamsAllValues.cs](../../../samples/BenchmarkDotNet.Samples/IntroParamsAllValues.cs)] | ||
|
||
### Output | ||
|
||
```markdown | ||
Method | E | B | Mean | Error | | ||
---------- |---- |------ |---------:|------:| | ||
Benchmark | A | ? | 101.9 ms | NA | | ||
Benchmark | A | False | 111.9 ms | NA | | ||
Benchmark | A | True | 122.3 ms | NA | | ||
Benchmark | BB | ? | 201.5 ms | NA | | ||
Benchmark | BB | False | 211.8 ms | NA | | ||
Benchmark | BB | True | 221.4 ms | NA | | ||
Benchmark | CCC | ? | 301.8 ms | NA | | ||
Benchmark | CCC | False | 312.3 ms | NA | | ||
Benchmark | CCC | True | 322.2 ms | NA | | ||
|
||
// * Legends * | ||
E : Value of the 'E' parameter | ||
B : Value of the 'B' parameter | ||
``` | ||
|
||
### Links | ||
|
||
* @docs.parameterization | ||
* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroParamsAllValues | ||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Threading; | ||
using BenchmarkDotNet.Attributes; | ||
|
||
namespace BenchmarkDotNet.Samples | ||
{ | ||
[DryJob] | ||
public class IntroParamsAllValues | ||
{ | ||
public enum CustomEnum | ||
{ | ||
A, | ||
BB, | ||
CCC | ||
} | ||
|
||
[ParamsAllValues] | ||
public CustomEnum E { get; set; } | ||
|
||
[ParamsAllValues] | ||
public bool? B { get; set; } | ||
|
||
[Benchmark] | ||
public void Benchmark() | ||
{ | ||
Thread.Sleep(E.ToString().Length * 100 + (B == true ? 20 : B == false ? 10 : 0)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using System; | ||
namespace BenchmarkDotNet.Attributes | ||
{ | ||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] | ||
public class ParamsAllValuesAttribute : Attribute | ||
{ | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
src/BenchmarkDotNet/Attributes/Validators/ParamsAllValuesValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using BenchmarkDotNet.Attributes; | ||
using BenchmarkDotNet.Extensions; | ||
|
||
namespace BenchmarkDotNet.Validators | ||
{ | ||
class ParamsAllValuesValidator : IValidator | ||
{ | ||
public static readonly ParamsAllValuesValidator FailOnError = new ParamsAllValuesValidator(); | ||
|
||
public bool TreatsWarningsAsErrors => true; | ||
|
||
private ParamsAllValuesValidator() { } | ||
|
||
private const BindingFlags reflectionFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; | ||
|
||
public IEnumerable<ValidationError> Validate(ValidationParameters input) => | ||
input.Benchmarks | ||
.Select(benchmark => benchmark.Descriptor.Type) | ||
.Distinct() | ||
.SelectMany(type => type.GetTypeMembersWithGivenAttribute<ParamsAllValuesAttribute>(reflectionFlags)) | ||
.Distinct() | ||
.Select(member => GetErrorOrDefault(member.ParameterType)) | ||
.Where(error => error != default); | ||
|
||
private bool IsBool(Type paramType) => paramType == typeof(bool); | ||
private bool IsEnum(Type paramType) => paramType.GetTypeInfo().IsEnum; | ||
private bool IsFlagsEnum(Type paramType) | ||
{ | ||
var typeInfo = paramType.GetTypeInfo(); | ||
return typeInfo.IsEnum && typeInfo.IsDefined(typeof(FlagsAttribute)); | ||
} | ||
private bool IsNullable(Type paramType, out Type underlyingType) | ||
{ | ||
underlyingType = Nullable.GetUnderlyingType(paramType); | ||
return underlyingType != null; | ||
} | ||
|
||
private ValidationError GetErrorOrDefault(Type parameterType) | ||
{ | ||
switch (parameterType) | ||
{ | ||
case Type t when IsNullable(t, out Type underType): | ||
return GetErrorOrDefault(underType); | ||
|
||
case Type t when IsFlagsEnum(t): | ||
return new ValidationError( | ||
TreatsWarningsAsErrors, | ||
$"Unable to use {parameterType.Name} with [ParamsAllValues], because it's flags enum."); | ||
|
||
case Type t when IsBool(t) || IsEnum(t): | ||
return default; | ||
|
||
default: | ||
return new ValidationError( | ||
TreatsWarningsAsErrors, | ||
$"Type {parameterType.Name} cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type."); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
...ramsAllValuesApprovalTests.BenchmarkShouldProduceSummary.WithAllValuesOfBool.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
=== WithAllValuesOfBool === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | False | 102.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | True | 202.0 ns | 6.088 ns | 1.581 ns | ^ | ||
|
||
Errors: 0 |
15 changes: 15 additions & 0 deletions
15
...ramsAllValuesApprovalTests.BenchmarkShouldProduceSummary.WithAllValuesOfEnum.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
=== WithAllValuesOfEnum === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | A | 102.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | B | 202.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | C | 302.0 ns | 6.088 ns | 1.581 ns | ^ | ||
|
||
Errors: 0 |
15 changes: 15 additions & 0 deletions
15
...aluesApprovalTests.BenchmarkShouldProduceSummary.WithAllValuesOfNullableBool.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
=== WithAllValuesOfNullableBool === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | ? | 102.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | False | 202.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | True | 302.0 ns | 6.088 ns | 1.581 ns | ^ | ||
|
||
Errors: 0 |
16 changes: 16 additions & 0 deletions
16
...aluesApprovalTests.BenchmarkShouldProduceSummary.WithAllValuesOfNullableEnum.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
=== WithAllValuesOfNullableEnum === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | ? | 102.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | A | 202.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | B | 302.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | C | 402.0 ns | 6.088 ns | 1.581 ns | ^ | ||
|
||
Errors: 0 |
14 changes: 14 additions & 0 deletions
14
...luesApprovalTests.BenchmarkShouldProduceSummary.WithNotAllowedFlagsEnumError.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
=== WithNotAllowedFlagsEnumError === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | 0 | 102.0 ns | 6.088 ns | 1.581 ns | | ||
|
||
Errors: 1 | ||
* Unable to use TestFlagsEnum with [ParamsAllValues], because it's flags enum. |
15 changes: 15 additions & 0 deletions
15
...sApprovalTests.BenchmarkShouldProduceSummary.WithNotAllowedNullableTypeError.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
=== WithNotAllowedNullableTypeError === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | ? | 102.0 ns | 6.088 ns | 1.581 ns | ^ | ||
Benchmark | 0 | 202.0 ns | 6.088 ns | 1.581 ns | ^ | ||
|
||
Errors: 1 | ||
* Type Int32 cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type. |
14 changes: 14 additions & 0 deletions
14
...AllValuesApprovalTests.BenchmarkShouldProduceSummary.WithNotAllowedTypeError.approved.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
=== WithNotAllowedTypeError === | ||
|
||
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V | ||
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores | ||
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC | ||
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION | ||
|
||
|
||
Method | ParamProperty | Mean | Error | StdDev | | ||
---------- |-------------- |---------:|---------:|---------:| | ||
Benchmark | 0 | 102.0 ns | 6.088 ns | 1.581 ns | | ||
|
||
Errors: 1 | ||
* Type Int32 cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type. |
Oops, something went wrong.