Skip to content

Performance changes when I use WithId #1342

@BorisTheBrave

Description

@BorisTheBrave

I've been investigating the performance of a benchmark i've created. I've been seeing a lot of weird behaviour, but I noticed one thing that appears to be specific to Benchmark.NET.

The following code demonstrates the problem: BorisTheBrave/DeBroglie@0b0f994

It runs a single test called Benchmarks.Free, under 3 different configurations:

            BenchmarkRunner
                .Run<Benchmarks>(
                    DefaultConfig.Instance
                        .With(Job.Default.WithId("A"))
                        .With(Job.Default)
                        .With(Job.Default.WithId("Z"))
                        );

All three should logically give the same result, but instead, the unnamed one is significantly faster.

On my machine:

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18362
Intel Core i5-8400 CPU 2.80GHz (Coffee Lake), 1 CPU, 6 logical and 6 physical cores
  [Host]     : .NET Framework 4.8 (4.8.4075.0), X64 RyuJIT
  DefaultJob : .NET Framework 4.8 (4.8.4075.0), X64 RyuJIT
  A          : .NET Framework 4.8 (4.8.4075.0), X64 RyuJIT
  Z          : .NET Framework 4.8 (4.8.4075.0), X64 RyuJIT


| Method |     Job |     Mean |     Error |    StdDev |
|------- |-------- |---------:|----------:|----------:|
|   Free | Default | 5.671 ms | 0.0240 ms | 0.0213 ms |
|   Free |       A | 6.187 ms | 0.0311 ms | 0.0291 ms |
|   Free |       Z | 5.967 ms | 0.0218 ms | 0.0204 ms |

Default is always under 5.7 ms, the others around 6ms. I get similar results in .NET Core 2.1.12.

Running the jobs in separate processes separately doesn't change performance (so it's not a JIT warming thing).

Note that this behaviour is very sensitive to changes - I've found changing random unused lines of code, turning on debug symbols etc causes the Default to take 6ms instead. I presume that WithId is making some similar subtle difference to the compiled assembly. This makes it hard for me to supply you with a smaller test case.

Using any With method seems to increase the runtime - I'm just illustrating with WithId as it seems clear to me it shouldn't have any effect.


In conclusion
Expected behaviour: Jobs Default and A should have similar performance
Actual behaviour: Default is significantly faster
Steps to reproduce: Checkout BorisTheBrave/DeBroglie@0b0f994, build DeBrogilie.Benchmark.exe and run it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions