BenchmarkDotNet
BenchmarkDotNet copied to clipboard
Add validation warning for `sealed` classes containing benchmarks
It is easy to create benchmarks, for example as shown in README.md:
// attributes here
public class Md5VsSha256
{
// setups and benchmarks here
}
However, if I choose to seal my class, as in:
public sealed class Md5VsSha256
then if I use BenchmarkSwitcher.FromAssemblies(...).Run(...) to run my benchmarks, then the class is no longer discovered.
Is there any technical reason for this behavior?
It seems that if you go to src/BenchmarkDotNet/Extensions/ReflectionExtensions.cs line 159 and remove the .IsSealed criterion, then this should work?
In the project I am working in, we prefer to make all types sealed unless they are specifically designed to be base classes, and this practice improves performance in general, so it is a shame if classes containing benchmarks cannot also be sealed.
Is there any technical reason for this behavior?
Your benchmark class cannot be sealed because BDN generates a class that inherits it in order to actually run the benchmarks. https://github.com/dotnet/BenchmarkDotNet/blob/e6fdc6b3c4d540983641f5aeca9c93308dc0da7a/src/BenchmarkDotNet/Templates/BenchmarkType.txt#L2
Perhaps it would be better to display a warning rather than ignore it silently.
@timcassell, All right, my question was based on general ignorance, and this is clearly much more complex than I had imagined.
There are likely a variety of different ways BenchmarkDotNet could be used. In our use, it seems the template was not used. But then I did not actually have the attribute [SimpleJob] on my class (called Md5VsSha256 in the example).
After having seen the template Templates/BenchmarkType.txt, if I do include [SimpleJob], and also introduce an evil member like:
public int BenchmarkDotNet { get; set; }
to make sure the code in the template will not compile, I do see output indicating the compile-time error, so I can see that a template is used then. However (removing the evil BenchmarkDotNet property), if I make a check in the constructor:
public Md5VsSha256()
{
if (GetType() != typeof(Md5VsSha256))
{
throw new InvalidOperationException("See, template type is instantiated.");
}
}
then I do not see any indication that the line 6 from the template, BenchmarkDotNet.Autogenerated.Runnable_$ID$ instance = new BenchmarkDotNet.Autogenerated.Runnable_$ID$(); // do NOT change name "instance" (used in SmartParamameter), is run, in my use.
Anyway, this is probably not worth pursuing further. Thank you for your answer.
We should reconsider writing the code analyzers for BDN, similar to what xUnit provides.