FAQ (Frequently asked questions)
Q Why can't I install BenchmarkDotNet in Visual Studio 2010/2012/2013?
A BenchmarkDotNet requires NuGet 3.x+ and can't be installed in old versions of Visual Studio which use NuGet 2.x. Consider to use Visual Studio 2015/2017 or Rider. See also: BenchmarkDotNet#237, roslyn#12780.
Q Why can't I install BenchmarkDotNet in a new .NET Core Console App in Visual Studio 2017?
A BenchmarkDotNet supports only netcoreapp2.0+. Some old Visual Studio 2017 can create a new application which targets netcoreapp1.0. You should upgrade it up to 2.0. If you want to target netcoreapp1.0 in your main assembly, it's recommended to create a separated project for benchmarks.
Q I created a new .NET Core Console App in Visual Studio 2017. Now I want to run my code on CoreCLR, full .NET Framework, and Mono. How can I do it?
A Use the following lines in your
.csproj
file:<TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks> <PlatformTarget>AnyCPU</PlatformTarget>
And mark your benchmark class with the following attributes:
[CoreJob, ClrJob, MonoJob]
Q My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires
net461
andnetcoreapp2.0
. How can I run benchmarks in this case?A It's a good practice to introduce an additional console application (e.g.
MyAwesomeLibrary.Benchmarks
) which will depend on your code and BenchmarkDotNet. Due to the fact that users usually run benchmarks in a develop environment and don't distribute benchmarks for users, it shouldn't be a problem.Q I wrote a small benchmark, but BenchmarkDotNet requires a lot of time for time measurements. How can I reduce this time?
A By default, BenchmarkDotNet automatically chooses a number of iterations which allows achieving the best precision. If you don't need such level of precision and just want to have a quick way to get approximated results, you can specify all parameters manually. For example, you can use the
SimpleJob
orShortRunJob
attributes:[SimpleJob(launchCount: 1, warmupCount: 3, iterationCount: 5, invocationCount:100, id: "QuickJob")] [ShortRunJob]
Q My benchmark unexpectedly stopped and I saw the information about error code. What can I do?
A BenchmarkDotNet generates, builds and runs new process for every benchmark. This behavior is sometimes interpreted by anti-virus as dangerous, and the process is killed. Use
EnvironmentAnalyser
to detect antivirus software and configure your benchmark to useInProcessToolchain
.Q Can I run benchmark on the virtual machine?
A Yes, of course. However, it can affect results because of the shared, physical machine, virtualization process and incorrect
Stopwatch.Frequency
. If you are unsure whether an application is running on virtual environment, useEnvironmentAnalyser
to detect VM hypervisor.Q I have failed to run my benchmarks, I am getting following errors about non-optimized dll. What can I do?
Assembly BenchmarkDotNet.Samples which defines benchmarks references non-optimized BenchmarkDotNet If you own this dependency, please, build it in RELEASE. If you don't, you can create custom config with DontFailOnError to disable our custom policy and allow this b Assembly BenchmarkDotNet.Samples which defines benchmarks is non-optimized Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.
A You should always run your benchmarks in RELEASE mode with optimizations enabled (default setting for RELEASE). However if you have to use non-optimized 3rd party assembly you have to create custom config to disable our default policy.
public class AllowNonOptimized : ManualConfig { public AllowNonOptimized() { Add(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS Add(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default Add(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default Add(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default } }
Q I have failed to run my benchmarks from LINQPad. How can I fix this problem?
Assembly LINQPadQuery which defines benchmarks references non-optimized LINQPad Assembly LINQPadQuery which defines benchmarks is non-optimized Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.
A You need to make sure that you are using AnyCPU 5.22.05+ build of LINQPad with optimizations enabled. To enable the optimizations you need to go to Preferences -> Query and select
compile with /optimize+
Q I'm trying to use
RPlotExporter
but there are no any images in theresults
folderA Try to specify
R_LIBS_USER
(e.g.R_LIBS_USER=/usr/local/lib/R/
on Linux/macOS, see also: #692)Q My benchmark failed with OutOfMemoryException. How can I fix this problem?
A BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects. If your benchmark allocates memory and keeps it alive, you are creating a memory leak.
You should redesign your benchmark and remove the side-effects. You can use
OperationsPerInvoke
,IterationSetup
andIterationCleanup
to do that.An example:
public class OOM { private StringBuilder buffer = new StringBuilder(); [Benchmark] public void HasSideEffects() { // This method is growing the buffer to infinity // because it's executed millions of times buffer.Append('a'); } [Benchmark(OperationsPerInvoke = 16)] public void HasNoSideEffects() { buffer.Clear(); for (int i = 0; i < 1024; i++) buffer.Append('a'); } }