dotnet / BenchmarkDotNet

Powerful .NET library for benchmarking
https://benchmarkdotnet.org
MIT License
10.54k stars 969 forks source link

Unexpected Runs of SetupMethods #2602

Closed swtrse closed 3 months ago

swtrse commented 3 months ago

After getting deeper into benchmarks and attempts to speed up certain tests I run into an unexpected behavior. I was wondering if that is intentional or I found a bug in the system.

My benchmark is designed like this

[ShortRunJob(RuntimeMoniker.Net80)]
[ShortRunJob(RuntimeMoniker.Net90)]
[GenericTypeArguments(typeof(int))]
[GenericTypeArguments(typeof(long))]
public class MyBenchmark<T> where T : notnull
{
    [Params(0,1,2)] public int MyProperty1 { get; [UsedImplicitly] set; }
    [Params(0,1,2)] public int MyProperty2 { get; [UsedImplicitly] set; }

   [GlobalSetup]
    public void A_Global_Setup()
    {
        // Very time consuming preparations....
    }

    [IterationSetup(Target = "Benchmark1")]
    public void A_Iteration_Setup_Benchmark1()
    {
        // Preparations needed for each testrun....
    }

   [IterationSetup(Target = "Benchmark2")]
    public void A_Iteration_Setup_Benchmark2()
    {
        // Preparations needed for each testrun....
    }

    [Benchmark]
    public void Benchmark1()
    {
        // Do Stuff
    }

    [Benchmark]
    public void Benchmark2()
    {
        // Do Stuff
    }
}

Now what I see in the Logs is that the Test runs like

I do get that Iteration Setups are running multiple times for Overhead detection. Prepare the prerequisites for each call of Benchmark1() and so on. That is ok. What looks like an error to me is that the Global Setup is running every time too. Even when the Benchmark Settings did not change. I noticed this because I wanted to do some heavy lifting in the Global Setup expecting that for each (Runtime, MyProperty1, MyProperty2, T) the Global Setup runs just once. So what I did expect was

timcassell commented 3 months ago

https://github.com/dotnet/BenchmarkDotNet/issues/2198#issuecomment-1319035590

swtrse commented 3 months ago

@timcassell I almost get a guilty conscience because I always have to follow up and disagree. I have now repeated the test with the Config (DebugInProcessConfig). GlobalSetup is also called several times in this case even if the setting parameters do not change.

timcassell commented 3 months ago

Disagree with what? I mentioned in that comment that it is ran once per benchmark. If you want it to only run once total, you have to make it behave that way manually.

swtrse commented 3 months ago

Ah I get it. I did misunderstood your comment in the other issue.