BenchmarkDotNet icon indicating copy to clipboard operation
BenchmarkDotNet copied to clipboard

Add grouping by type

Open YegorStepanov opened this issue 3 years ago • 6 comments
trafficstars

Fixes #1164 Fixes #2022

Look at "Update existing tests" and "Update new tests" to see what has changed.

Fixes:

https://github.com/dotnet/BenchmarkDotNet/issues/1164#issue-448217544

Master:

|       Type | Method |     Mean |    Error |   StdDev | Ratio |
|----------- |------- |---------:|---------:|---------:|------:|
| Formatting |    Old | 15.52 ms | 0.306 ms | 0.017 ms |  1.00 |
|    Parsing |    Old | 15.54 ms | 1.847 ms | 0.101 ms |  1.00 |
| Formatting |    New | 15.48 ms | 2.415 ms | 0.132 ms |  1.00 |
|    Parsing |    New | 15.49 ms | 1.244 ms | 0.068 ms |  1.00 |

PR:

|       Type | Method |     Mean |    Error |   StdDev | Ratio |
|----------- |------- |---------:|---------:|---------:|------:|
| Formatting |    Old | 15.46 ms | 0.039 ms | 0.035 ms |  1.00 |
| Formatting |    New | 15.62 ms | 0.081 ms | 0.075 ms |  1.01 |
|            |        |          |          |          |       |
|    Parsing |    Old | 15.59 ms | 0.039 ms | 0.036 ms |  1.00 |
|    Parsing |    New | 15.54 ms | 0.076 ms | 0.071 ms |  1.00 |

https://github.com/dotnet/BenchmarkDotNet/issues/2022#issue-1279202717

Master:

         Type |       Method | Pending |     Mean |   Error |  StdDev | LogicalGroup |
------------- |------------- |-------- |---------:|--------:|--------:|------------- |
   AsyncAwait |     Callback |   False | 102.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith |     Callback |   False | 102.0 ns | 6.09 ns | 1.58 ns |            * |
   AsyncAwait | ProtoPromise |   False | 202.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith | ProtoPromise |   False | 202.0 ns | 6.09 ns | 1.58 ns |            * |
   AsyncAwait |   RsgPromise |   False | 302.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith |   RsgPromise |   False | 302.0 ns | 6.09 ns | 1.58 ns |            * |
   AsyncAwait |         Task |   False | 402.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith |         Task |   False | 402.0 ns | 6.09 ns | 1.58 ns |            * |
   AsyncAwait |      UniTask |   False | 502.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith |      UniTask |   False | 502.0 ns | 6.09 ns | 1.58 ns |            * |
   AsyncAwait |    ValueTask |   False | 602.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWith |    ValueTask |   False | 602.0 ns | 6.09 ns | 1.58 ns |            * |

PR

         Type |       Method | Pending |     Mean |   Error |  StdDev | LogicalGroup |
------------- |------------- |-------- |---------:|--------:|--------:|------------- |
   AsyncAwait |     Callback |   False | 102.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
   AsyncAwait | ProtoPromise |   False | 202.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
   AsyncAwait |   RsgPromise |   False | 302.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
   AsyncAwait |         Task |   False | 402.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
   AsyncAwait |      UniTask |   False | 502.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
   AsyncAwait |    ValueTask |   False | 602.0 ns | 6.09 ns | 1.58 ns |   AsyncAwait |
              |              |         |          |         |         |              |
 ContinueWith |     Callback |   False | 102.0 ns | 6.09 ns | 1.58 ns | ContinueWith |
 ContinueWith | ProtoPromise |   False | 202.0 ns | 6.09 ns | 1.58 ns | ContinueWith |
 ContinueWith |   RsgPromise |   False | 302.0 ns | 6.09 ns | 1.58 ns | ContinueWith |
 ContinueWith |         Task |   False | 402.0 ns | 6.09 ns | 1.58 ns | ContinueWith |
 ContinueWith |      UniTask |   False | 502.0 ns | 6.09 ns | 1.58 ns | ContinueWith |
 ContinueWith |    ValueTask |   False | 602.0 ns | 6.09 ns | 1.58 ns | ContinueWith |

https://github.com/dotnet/BenchmarkDotNet/issues/1864#issuecomment-1001346715

Master

                  Type |          Method |   N |     Mean |   Error |  StdDev | LogicalGroup |
---------------------- |---------------- |---- |---------:|--------:|--------:|------------- |
          AsyncPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
         AsyncResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
          AwaitPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
         AwaitResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWithFromValue | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
   ContinueWithPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
  ContinueWithResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |            * |
          AsyncPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
         AsyncResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
          AwaitPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
         AwaitResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
 ContinueWithFromValue | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
   ContinueWithPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |
  ContinueWithResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |            * |

PR

                  Type |          Method |   N |     Mean |   Error |  StdDev |          LogicalGroup |
---------------------- |---------------- |---- |---------:|--------:|--------:|---------------------- |
          AsyncPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |          AsyncPending |
          AsyncPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |          AsyncPending |
                       |                 |     |          |         |         |                       |
         AsyncResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |         AsyncResolved |
         AsyncResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |         AsyncResolved |
                       |                 |     |          |         |         |                       |
          AwaitPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |          AwaitPending |
          AwaitPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |          AwaitPending |
                       |                 |     |          |         |         |                       |
         AwaitResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |         AwaitResolved |
         AwaitResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |         AwaitResolved |
                       |                 |     |          |         |         |                       |
 ContinueWithFromValue | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns | ContinueWithFromValue |
 ContinueWithFromValue | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns | ContinueWithFromValue |
                       |                 |     |          |         |         |                       |
   ContinueWithPending | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |   ContinueWithPending |
   ContinueWithPending | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |   ContinueWithPending |
                       |                 |     |          |         |         |                       |
  ContinueWithResolved | ProtoPromise_V1 | 100 | 102.0 ns | 6.09 ns | 1.58 ns |  ContinueWithResolved |
  ContinueWithResolved | ProtoPromise_V2 | 100 | 202.0 ns | 6.09 ns | 1.58 ns |  ContinueWithResolved |

https://github.com/dotnet/BenchmarkDotNet/issues/1864#issuecomment-1031364986

Master

                 Type |           Method |     Mean |   Error |  StdDev | LogicalGroup |
--------------------- |----------------- |---------:|--------:|--------:|------------- |
      ArrayBenchmarks |            Empty | 102.0 ns | 6.09 ns | 1.58 ns |            * |
      EmptyBenchmarks |  EnumerableEmpty | 102.0 ns | 6.09 ns | 1.58 ns |            * |
 EnumerableBenchmarks |            Empty | 102.0 ns | 6.09 ns | 1.58 ns |            * |
     StringBenchmarks | ConstructorArray | 102.0 ns | 6.09 ns | 1.58 ns |            * |
      EmptyBenchmarks |       ArrayEmpty | 202.0 ns | 6.09 ns | 1.58 ns |            * |
     StringBenchmarks |  ConstructorSpan | 202.0 ns | 6.09 ns | 1.58 ns |            * |

PR

                 Type |           Method |     Mean |   Error |  StdDev |         LogicalGroup |
--------------------- |----------------- |---------:|--------:|--------:|--------------------- |
      ArrayBenchmarks |            Empty | 102.0 ns | 6.09 ns | 1.58 ns |      ArrayBenchmarks |
                      |                  |          |         |         |                      |
      EmptyBenchmarks |  EnumerableEmpty | 102.0 ns | 6.09 ns | 1.58 ns |      EmptyBenchmarks |
      EmptyBenchmarks |       ArrayEmpty | 202.0 ns | 6.09 ns | 1.58 ns |      EmptyBenchmarks |
                      |                  |          |         |         |                      |
 EnumerableBenchmarks |            Empty | 102.0 ns | 6.09 ns | 1.58 ns | EnumerableBenchmarks |
                      |                  |          |         |         |                      |
     StringBenchmarks | ConstructorArray | 102.0 ns | 6.09 ns | 1.58 ns |     StringBenchmarks |
     StringBenchmarks |  ConstructorSpan | 202.0 ns | 6.09 ns | 1.58 ns |     StringBenchmarks |

Tests

Yes, that's a lot of tests, but now it's easy to change the ordering logic as there are a lot of cases covered.

For example, this change produces a better output, but it breaks output for OneBaseline in some test (it starts display baseline numbers instead a question mark):

- if (hasMultipleTypes)
+ if (hasMultipleTypes && explicitRules.IsEmpty())

Question

What is the correct table for this?

[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]
[LogicalGroupColumn, CategoriesColumn, BaselineColumn]
[BenchmarkCategory("A")]
[SimpleJob(id: "Job1"), SimpleJob(id: "Job2")]
public class Bench1
{
    [Params(10, 20)] public int Param;
    [Benchmark(Baseline = true)] public void Foo() { }
    [Benchmark] public void Bar() { }
}

[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]
[LogicalGroupColumn, CategoriesColumn, BaselineColumn]
[BenchmarkCategory("B")]
public class Bench2
{
    [Params(10, 20)] public int Param;
    [Benchmark(Baseline = true)] public void Foo() { }
    [Benchmark] public void Bar() { }
}

Master/PR output is:

   Type | Method |        Job | Categories | Param |     Mean |   Error |  StdDev | Ratio | RatioSD |                     LogicalGroup | Baseline |
------- |------- |----------- |----------- |------ |---------:|--------:|--------:|------:|--------:|--------------------------------- |--------- |
 Bench1 |    Foo |       Job1 |          A |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job1 |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job2 |          A |    10 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job2 |      Yes |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job1 |          A |    20 | 502.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job1 |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job2 |          A |    20 | 702.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job2 |      Yes |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Foo | DefaultJob |          B |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=10]-DefaultJob |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Foo | DefaultJob |          B |    20 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=20]-DefaultJob |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job1 |          A |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job1 |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job2 |          A |    10 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job2 |       No |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job1 |          A |    20 | 602.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job1 |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job2 |          A |    20 | 802.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job2 |       No |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Bar | DefaultJob |          B |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=10]-DefaultJob |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Bar | DefaultJob |          B |    20 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=20]-DefaultJob |       No | ^

YegorStepanov avatar Oct 18 '22 22:10 YegorStepanov

Question

What is the correct table for this?

Old, wrong answer

If [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)] just moves that order in front, and the other defaults remain in the same order, and if we add ByType so the order should be [ByMethod, ByType, ByCategory, ByParams, ByJob], I think it should look like this:

  Type | Method |        Job | Categories | Param |     Mean |   Error |  StdDev | Ratio | RatioSD |                     LogicalGroup | Baseline |
------- |------- |----------- |----------- |------ |---------:|--------:|--------:|------:|--------:|--------------------------------- |--------- |
Bench1 |    Foo |       Job1 |          A |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job1 |      Yes | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Foo |       Job2 |          A |    10 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job2 |      Yes |
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Foo |       Job1 |          A |    20 | 502.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job1 |      Yes | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Foo |       Job2 |          A |    20 | 702.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job2 |      Yes |
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench2 |    Foo | DefaultJob |          B |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=10]-DefaultJob |      Yes | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench2 |    Foo | DefaultJob |          B |    20 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=20]-DefaultJob |      Yes | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Bar |       Job1 |          A |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job1 |       No | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Bar |       Job2 |          A |    10 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job2 |       No |
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Bar |       Job1 |          A |    20 | 602.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job1 |       No | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench1 |    Bar |       Job2 |          A |    20 | 802.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job2 |       No |
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench2 |    Bar | DefaultJob |          B |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=10]-DefaultJob |       No | ^
       |        |            |            |       |          |         |         |       |         |                                  |          |
Bench2 |    Bar | DefaultJob |          B |    20 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=20]-DefaultJob |       No | ^

[Edit] Oh wait, I think I misunderstood the question. Because the [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)] could be applied to one Type, and a different [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams)] could be applied to a different type, so how should the table look then?

In that case, I think ByType should always be first, unless the group rule is overridden in the config for the entire run (not per type). And each Type should have its own group rule set, since they can be set individually on each Type.

With that said, I think that table should look like this:

   Type | Method |        Job | Categories | Param |     Mean |   Error |  StdDev | Ratio | RatioSD |                     LogicalGroup | Baseline |
------- |------- |----------- |----------- |------ |---------:|--------:|--------:|------:|--------:|--------------------------------- |--------- |
 Bench1 |    Foo |       Job1 |          A |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job1 |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job2 |          A |    10 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=10]-Job2 |      Yes |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job1 |          A |    20 | 502.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job1 |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Foo |       Job2 |          A |    20 | 702.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 |       Foo-Bench1-[Param=20]-Job2 |      Yes |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job1 |          A |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job1 |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job2 |          A |    10 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=10]-Job2 |       No |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job1 |          A |    20 | 602.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job1 |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench1 |    Bar |       Job2 |          A |    20 | 802.0 ns | 6.09 ns | 1.58 ns |     ? |       ? |       Bar-Bench1-[Param=20]-Job2 |       No |
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Foo | DefaultJob |          B |    10 | 102.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=10]-DefaultJob |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Bar | DefaultJob |          B |    10 | 202.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=10]-DefaultJob |       No | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Foo | DefaultJob |          B |    20 | 302.0 ns | 6.09 ns | 1.58 ns |  1.00 |    0.00 | Foo-Bench2-[Param=20]-DefaultJob |      Yes | ^
        |        |            |            |       |          |         |         |       |         |                                  |          |
 Bench2 |    Bar | DefaultJob |          B |    20 | 402.0 ns | 6.09 ns | 1.58 ns |     ? |       ? | Bar-Bench2-[Param=20]-DefaultJob |       No | ^

timcassell avatar Oct 18 '22 22:10 timcassell

A follow-up to this may want to add a ByRuntime group rule, which by default should be ordered before ByType.

timcassell avatar Oct 18 '22 23:10 timcassell

I don't like that grouping ByMethod groups them into separate groups, but this seems to be the correct behavior:

How the grouping works:

  1. Look at the LogicalGroup column. It shows the keys to sort by (the keys are truncated from the right if ALL keys in the table are the same)

  2. There is default grouping order: ByType, ByCategory, ByParams, ByJob, ByMethod

  3. When we add a grouping manually ([GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]) it adds this key to the left. So it turns out that the groups consist of 1 element.

YegorStepanov avatar Oct 18 '22 23:10 YegorStepanov

I'm converting it to draft until I figure out why nothing changes due to swapping ByCategory<->ByType

[Edit] There is no difference in order because we always break them into groups if there are multiple types.

YegorStepanov avatar Oct 18 '22 23:10 YegorStepanov

I made the most conservative mode. I don't like that there were more groups than I expected (look at the last commit)

assign to @AndreyAkinshin

YegorStepanov avatar Oct 21 '22 15:10 YegorStepanov

@YegorStepanov I tried these changes and, while it looks better, there's still some weirdness with the table:

|         Type |       Method | Pending |       Mean | Ratio |
|------------- |------------- |-------- |-----------:|------:|
|   AsyncAwait |     Callback |   False |   358.8 ns |  1.00 |
|   AsyncAwait | ProtoPromise |   False |   378.7 ns |  1.05 |
|   AsyncAwait |   RsgPromise |   False |         NA |     ? |
|   AsyncAwait |         Task |   False |   357.7 ns |  1.00 |
|   AsyncAwait |      UniTask |   False |   392.3 ns |  1.09 |
|   AsyncAwait | UnityFxAsync |   False |   538.7 ns |  1.50 |
|   AsyncAwait |    ValueTask |   False |   522.7 ns |  1.46 |
| ContinueWith |     Callback |   False |   347.8 ns |  0.97 |
| ContinueWith | ProtoPromise |   False |   529.0 ns |  1.47 |
| ContinueWith |   RsgPromise |   False |   707.7 ns |  1.97 |
| ContinueWith |         Task |   False | 2,372.0 ns |  6.61 |
| ContinueWith |      UniTask |   False |   742.5 ns |  2.07 |
| ContinueWith | UnityFxAsync |   False | 1,807.4 ns |  5.03 |
| ContinueWith |    ValueTask |   False |         NA |     ? |
|              |              |         |            |       |
|   AsyncAwait |     Callback |    True |   417.9 ns |  1.00 |
|   AsyncAwait | ProtoPromise |    True | 2,166.3 ns |  5.05 |
|   AsyncAwait |   RsgPromise |    True |         NA |     ? |
|   AsyncAwait |         Task |    True | 2,710.6 ns |  6.27 |
|   AsyncAwait |      UniTask |    True | 1,910.4 ns |  4.44 |
|   AsyncAwait | UnityFxAsync |    True | 2,436.0 ns |  5.64 |
|   AsyncAwait |    ValueTask |    True | 3,120.2 ns |  7.26 |
| ContinueWith |     Callback |    True |   396.3 ns |  0.92 |
| ContinueWith | ProtoPromise |    True | 2,380.8 ns |  5.55 |
| ContinueWith |   RsgPromise |    True | 6,537.0 ns | 15.58 |
| ContinueWith |         Task |    True | 3,122.0 ns |  7.22 |
| ContinueWith |      UniTask |    True | 3,172.6 ns |  7.34 |
| ContinueWith | UnityFxAsync |    True | 2,749.3 ns |  6.36 |
| ContinueWith |    ValueTask |    True |         NA |     ? |

It seems to be grouping the parameter ahead of the type, and the ratio column is not segregated for each type (it's shared for the entire parameter, regardless of type).

public abstract class AsyncBenchmark
{
    [Params(true, false)]
    public bool Pending;
}

public partial class AsyncAwait : AsyncBenchmark
{
}

public partial class ContinueWith : AsyncBenchmark
{
}

timcassell avatar Dec 24 '22 10:12 timcassell