-
-
Notifications
You must be signed in to change notification settings - Fork 992
Fix array comparison in params #2153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
=== ParamArray === | ||
|
||
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 | ||
DefaultJob : extra output line | ||
|
||
|
||
Method | Param | Mean | Error | StdDev | Ratio | RatioSD | LogicalGroup | Baseline | | ||
------- |-------- |---------:|--------:|--------:|------:|--------:|--------------------- |--------- | | ||
Foo | Byte[1] | 102.0 ns | 6.09 ns | 1.58 ns | 1.00 | 0.00 | [Param=0]-DefaultJob | Yes | | ||
Foo | Byte[1] | 202.0 ns | 6.09 ns | 1.58 ns | 1.98 | 0.02 | [Param=0]-DefaultJob | Yes | | ||
Bar | Byte[1] | 302.0 ns | 6.09 ns | 1.58 ns | 2.96 | 0.03 | [Param=0]-DefaultJob | No | | ||
Bar | Byte[1] | 402.0 ns | 6.09 ns | 1.58 ns | 3.94 | 0.05 | [Param=0]-DefaultJob | No | | ||
| | | | | | | | | | ||
Foo | Byte[1] | 502.0 ns | 6.09 ns | 1.58 ns | 1.00 | 0.00 | [Param=1]-DefaultJob | Yes | | ||
Bar | Byte[1] | 602.0 ns | 6.09 ns | 1.58 ns | 1.20 | 0.00 | [Param=1]-DefaultJob | No | | ||
|
||
Errors: 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
=== ParamArrayOfArrays === | ||
|
||
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 | ||
DefaultJob : extra output line | ||
|
||
|
||
Method | Param | Mean | Error | StdDev | Ratio | RatioSD | LogicalGroup | Baseline | | ||
------- |----------- |---------:|--------:|--------:|------:|--------:|----------------------- |--------- | | ||
Foo | Int32[][2] | 102.0 ns | 6.09 ns | 1.58 ns | 1.00 | 0.00 | [Param=0,0]-DefaultJob | Yes | | ||
Foo | Int32[][2] | 302.0 ns | 6.09 ns | 1.58 ns | 2.96 | 0.03 | [Param=0,0]-DefaultJob | Yes | | ||
Bar | Int32[][2] | 402.0 ns | 6.09 ns | 1.58 ns | 3.94 | 0.05 | [Param=0,0]-DefaultJob | No | | ||
Bar | Int32[][2] | 602.0 ns | 6.09 ns | 1.58 ns | 5.90 | 0.08 | [Param=0,0]-DefaultJob | No | | ||
| | | | | | | | | | ||
Foo | Int32[][2] | 202.0 ns | 6.09 ns | 1.58 ns | 1.00 | 0.00 | [Param=0,1]-DefaultJob | Yes | | ||
Bar | Int32[][2] | 502.0 ns | 6.09 ns | 1.58 ns | 2.49 | 0.01 | [Param=0,1]-DefaultJob | No | | ||
|
||
Errors: 0 |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,5 @@ | ||||||
using System; | ||||||
using System.Collections.Generic; | ||||||
using System.Diagnostics.CodeAnalysis; | ||||||
using System.Globalization; | ||||||
using System.Linq; | ||||||
|
@@ -225,8 +226,8 @@ [Benchmark] public void Bar() { } | |||||
[SimpleJob(id: "Job1", baseline: true), SimpleJob(id: "Job2")] | ||||||
public class MethodJobBaseline_MethodsJobs | ||||||
{ | ||||||
[Benchmark(Baseline = true)] public void Foo() {} | ||||||
[Benchmark] public void Bar() {} | ||||||
[Benchmark(Baseline = true)] public void Foo() { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
|
||||||
[RankColumn, LogicalGroupColumn, BaselineColumn] | ||||||
|
@@ -235,25 +236,25 @@ public class MethodJobBaseline_MethodsJobsParams | |||||
{ | ||||||
[Params(2, 10), UsedImplicitly] public int Param; | ||||||
|
||||||
[Benchmark(Baseline = true)] public void Foo() {} | ||||||
[Benchmark] public void Bar() {} | ||||||
[Benchmark(Baseline = true)] public void Foo() { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
|
||||||
/* Invalid */ | ||||||
|
||||||
[RankColumn, LogicalGroupColumn, BaselineColumn] | ||||||
public class Invalid_TwoMethodBaselines | ||||||
{ | ||||||
[Benchmark(Baseline = true)] public void Foo() {} | ||||||
[Benchmark(Baseline = true)] public void Bar() {} | ||||||
[Benchmark(Baseline = true)] public void Foo() { } | ||||||
[Benchmark(Baseline = true)] public void Bar() { } | ||||||
} | ||||||
|
||||||
[RankColumn, LogicalGroupColumn, BaselineColumn] | ||||||
[SimpleJob(id: "Job1", baseline: true), SimpleJob(id: "Job2", baseline: true)] | ||||||
public class Invalid_TwoJobBaselines | ||||||
{ | ||||||
[Benchmark] public void Foo() {} | ||||||
[Benchmark] public void Bar() {} | ||||||
[Benchmark] public void Foo() { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
|
||||||
/* Escape Params */ | ||||||
|
@@ -262,10 +263,41 @@ public class Escape_ParamsAndArguments | |||||
{ | ||||||
[Params("\t", "\n"), UsedImplicitly] public string StringParam; | ||||||
|
||||||
[Arguments('\t')] [Arguments('\n')] | ||||||
[Benchmark] public void Foo(char charArg) {} | ||||||
[Benchmark] public void Bar() {} | ||||||
[Arguments('\t'), Arguments('\n')] | ||||||
[Benchmark] public void Foo(char charArg) { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
|
||||||
/* Param Arrays */ | ||||||
|
||||||
[BaselineColumn] | ||||||
[LogicalGroupColumn] | ||||||
public class ParamArray | ||||||
{ | ||||||
[Params(new byte[] { 0 }, new byte[] { 1 }, new byte[] { 0 })] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do we gain by having duplicate params (
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You want to remove the purpose of these tests and PR :)These tests check that arrays can be grouped if they have the same primitive values (but they are actually different arrays). We can disallow duplicate arguments for But how can we disable it for [ParamSource]?If the values are not primitive, it fallbacks to x.ToString().CompareTo(y.String()) == 0 //always if .ToString is not overloaded UniqueArgumentsValidatorIf I remember correctly, you can't distinguish between [Params] and [ParamSource] values, so [ArgumentSource("GetValues")]
[Benchmark]
public void Benchmark(MyType instance) { }
public IEnumerable<MyType> GetValues()
{
// fails because both ToString() are equal:
yield return new MyType { Value = 10 };
yield return new MyType { Value = 100 };
}
public class MyType { public int Value; } There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the type implements if(IComparableComparer.TryCompareTo(x, y, var userCompareTo))
return userCompareTo; But it works for primitives/arrays. Are you satisfied with the current implementation, or should I remake it? |
||||||
public byte[] Param; | ||||||
|
||||||
[Benchmark(Baseline = true)] public void Foo() { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
|
||||||
[BaselineColumn] | ||||||
[LogicalGroupColumn] | ||||||
public class ParamArrayOfArrays | ||||||
{ | ||||||
[ParamsSource(nameof(GetValues))] | ||||||
public int[][] Param; | ||||||
|
||||||
public IEnumerable<int[][]> GetValues() | ||||||
{ | ||||||
yield return new int[][] { new[] { 0 }, new[] { 0 }, }; | ||||||
yield return new int[][] { new[] { 0 }, new[] { 1 }, }; | ||||||
yield return new int[][] { new[] { 0 }, new[] { 0 }, }; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. answered above |
||||||
} | ||||||
|
||||||
[Benchmark(Baseline = true)] public void Foo() { } | ||||||
[Benchmark] public void Bar() { } | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was surprised to see that it works, then I've checked and found that we are relying on the
.ToString
comparison:BenchmarkDotNet/src/BenchmarkDotNet/Parameters/ParameterComparer.cs
Line 49 in 58d4bae
It would be more future proof to perform an explicit check:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code works like this:
So, if the
x=0 and y=0
, it exits on the last line:Future
Also, we need to add support for user
IComparable
types here, so the code will look like:Stuns but looks elegant