Search code examples
c#bitmapbenchmarkdotnet

How to do setup for microbencharks?


I'm trying to benchmark how long rotating different image resolutions takes. Each benchmark will be rotating the given Bitmap, and is therefore editing it. I want to reset this bitmap before each benchmark, so I looked into the [IterationSetup] attribute. The docs say, however, that this should not be used for microbencmarks. Since rotating a Bitmap takes less than 100ms and therefore is a microbenchmark, I was wondering how would I go about doing Setup for such a problem if I can't use [IterationSetup]?


Solution

  • The way I would do things like this is to write a unit test that measures the performance using a stopwatch, and writes the result to the console. Using R# or other plugins you can easily run such unit tests within visual studio.

    You can then either just delete the test once you have learned what you want to learn, add an attribute to ignore the test with some suitable comment, or setup some system to monitor the times.

    The main advantage of this is that it is low effort, at least if you already have a unit test project. For the types of performance testing I do it is usually sufficient, I'm usually more concerned the order of magnitude than any small differences.

    Benchmark.Net should give much better numbers, but will require more effort setup unless you already have a project for this. I have little experience with Benchmar.Net, but reading the documentation it seems like the GlobalSetup would be more appropriate than IterationSetup:

    A method which is marked by the [GlobalSetup] attribute will be executed only once per a benchmarked method after initialization of benchmark parameters and before all the benchmark method invocations. A method which is marked by the [GlobalCleanup] attribute will be executed only once per a benchmarked method after all the benchmark method invocations. If you are using some unmanaged resources (e.g., which were created in the GlobalSetup method), they can be disposed in the GlobalCleanup method.

    I.e. setup a parameter for your image size, and create your bitmap in the GlobalSetup. That is under the assumption that your rotate method writes to a new bitmap, and leaves the original untouched. At least that is the way I would write a rotate method. Otherwise you could just rotate the same bitmap in place multiple times, the performance should not be affected by the actual data in the pixels.