Code Monkey home page Code Monkey logo

benchmarkdotnet's People

Contributors

adamsitnik avatar alinasmirnova avatar andreyakinshin avatar dlemstra avatar epeshk avatar fransbouma avatar gigi81 avatar gsomix avatar ig-sinicyn avatar kant2002 avatar ky7m avatar lahma avatar lukasz-pyrzyk avatar martincostello avatar mattwarren avatar mawosoft avatar mfilippov avatar michalstrehovsky avatar morgan-kn avatar naricc avatar radekdoulik avatar radical avatar redknightlois avatar rizzen avatar tebeco avatar teknikaali avatar timcassell avatar wojciechnagorski avatar yegorstepanov avatar yohdeadfall avatar

benchmarkdotnet's Issues

Benchmark parameter disposal

See https://github.com/mawosoft/BenchmarkDotNet.Tests/tree/master/BDNParamDisposal
for parameter/argument creation and disposal in BDN host and in generated projects.

The generated code does not dispose the actually used parameters/arguments at all. Disposal occurs only while enumerating a ParamsSource or ArgumentsSource to skip to the current one and only for the ones skipped:

foreach (T parameter in parameters)
{
if (count == index)
{
return parameter;
}
if (parameter is IDisposable disposable)
{
// parameters might contain locking finalizers which might cause the benchmarking process to hung at the end
// to avoid that, we dispose the parameters that were created, but won't be used
// (for every test case we have to enumerate the underlying source enumerator and stop when we reach index of given test case)
// See https://github.com/dotnet/BenchmarkDotNet/issues/1383 and https://github.com/dotnet/runtime/issues/314 for more
disposable.Dispose();
}
count++;
}

BDN host only disposes benchmarks it actually runs and only after they all have been run:

// some benchmarks might be using parameters that have locking finalizers
// so we need to dispose them after we are done running the benchmarks
// see https://github.com/dotnet/BenchmarkDotNet/issues/1383 and https://github.com/dotnet/runtime/issues/314 for more
foreach (var benchmarkInfo in benchmarkRunInfos)
{
benchmarkInfo.Dispose();
}

The IDisposable chain goes: BenchmarkRunInfo -> BenchmarkCase(s) -> ParameterInstances -> ParameterInstance(s) -> (Value as IDisposable)?

However, BenchmarkCase(s) - and therefore ParameterInstance(s) - have been already created early and have gone through filters and validators.

  • If some are filtered out, they are not disposed.
  • If any validator reports a critical error, none are disposed at all.

The problem is that ParameterInstance(s) are constructed per method. Multiple job definitions share the same cached instances. Thus a filtered BenchmarkCase cannot be disposed because it might share ParameterInstance(s) with benchmarks that are about to be run.

ReturnValueValidator doesn't support Arguments?

  • ExecutionValidator(Base) has been written before introduction of Arguments and wasn't updated accordingly.
  • ReturnValueValidator was written later(?), but is based on ExecutionValidatorBase => no ArgumentsSupport.
    It also uses InProcessNoEmitToolchain.FillMembers() which handles Params only.
  • Both call WorkloadMethod.Invoke() with null for arguments.

Not sure if these validators are used anymore. They probably wouldn't have worked for our use case in XmlBenchmarks anyway due to lack of arguments equality (not sure about byte array equality, but ParamWrapper currently is in the way, see mawosoft/Mawosoft.Extensions.BenchmarkDotNet#22).

ConfigCompatibilityValidator should also check for multiple SummaryStyle(s)

public class ConfigCompatibilityValidator : IValidator
{
public static readonly ConfigCompatibilityValidator FailOnError = new ConfigCompatibilityValidator();
public bool TreatsWarningsAsErrors => true;
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)
{
var orderers =
validationParameters
.Benchmarks
.Where(benchmark => benchmark.Config.Orderer != Order.DefaultOrderer.Instance)
.Select(benchmark => benchmark.Config.Orderer)
.Distinct();
if (orderers.Count() > 1)
yield return new ValidationError(true, "You use JoinSummary options, but provided configurations cannot be joined. Only one Orderer per benchmark cases is allowed.");
}
}

At the moment such a case simply results in an exception here:
private static SummaryStyle GetConfiguredSummaryStyleOrNull(ImmutableArray<BenchmarkCase> benchmarkCases)
=> benchmarkCases.Select(benchmark => benchmark.Config.SummaryStyle).Distinct().SingleOrDefault();

... which is called only here (ctor):
Style = GetConfiguredSummaryStyleOrNull(BenchmarksCases)?.WithCultureInfo(cultureInfo);

A bit problematic since SummaryStyle can be null which seems to mean SummaryStyle.Default.

Mismatch between containingType and benchmarkMethods is ignored during benchmark conversion

Affects:

public static class BenchmarkConverter {
    public static BenchmarkRunInfo MethodsToBenchmarks(Type containingType, MethodInfo[] benchmarkMethods, IConfig config = null) {}
}
public static class BenchmarkRunner {
    public static Summary Run(Type type, MethodInfo[] methods, IConfig config = null) {}
} 
  • BDN doesn't check if the given MethodInfos belong to the given Type and will convert the methods anyway.
  • In case of a mismatch, the DisplayInfo will be wrong because BDN combines the class name from Type with the method name from MethodInfo despite the latter having a different ReflectedType (DeclaringType can be different if base class).
  • For out-of-process jobs, building the auto-generated boilerplate code fails, because the Runnable_0 etc classes are derived from the wrong type.
  • In-process jobs are executed w/o failing, but display the wrong info.

UnionRule is not copied with ManualConfig.Add() and methods that rely on Add(): Create(), Union().

Introduced in 854633f

[PublicAPI] public ConfigUnionRule UnionRule { get; set; } = ConfigUnionRule.Union;
public void Add(IConfig config)
{
columnProviders.AddRange(config.GetColumnProviders());
exporters.AddRange(config.GetExporters());
loggers.AddRange(config.GetLoggers());
diagnosers.AddRange(config.GetDiagnosers());
analysers.AddRange(config.GetAnalysers());
jobs.AddRange(config.GetJobs());
validators.AddRange(config.GetValidators());
hardwareCounters.AddRange(config.GetHardwareCounters());
filters.AddRange(config.GetFilters());
Orderer = config.Orderer ?? Orderer;
ArtifactsPath = config.ArtifactsPath ?? ArtifactsPath;
CultureInfo = config.CultureInfo ?? CultureInfo;
SummaryStyle = config.SummaryStyle ?? SummaryStyle;
logicalGroupRules.AddRange(config.GetLogicalGroupRules());
Options |= config.Options;
}

For Add() and Create() this is definitely a bug, however with Union() I'm not so sure. If localConfig was selected via LocalOnly, it might make sense to go back to Union for the resulting config???

Furthermore, Union() ALWAYS uses the UnionRule from localConfig.

  • Why would a localConfig specify GlobalOnly?
  • Setting GlobalOnly in the globalConfig has no effect. One would expect that to take precedence.

Explain use of asterisk (*) as valid input for BenchmarkSwitcher

string filterExample = "--filter " + UserInteractionHelper.EscapeCommandExample($"*{benchmarkCaptionExample}*");
logger.WriteLineHelp($"You should select the target benchmark(s). Please, print a number of a benchmark (e.g. `0`) or a contained benchmark caption (e.g. `{benchmarkCaptionExample}`).");
logger.WriteLineHelp("If you want to select few, please separate them with space ` ` (e.g. `1 2 3`).");
logger.WriteLineHelp($"You can also provide the class name in console arguments by using --filter. (e.g. `{filterExample}`).");

SmartParamBuilder casting should use target type, not source type.

in SmartParameter.ToSourceCode():

string cast = Value == null ? string.Empty : $"({Value.GetType().GetCorrectCSharpTypeName()})";

Similar issue was fixed in SmartArgument.ToSourceCode():

string cast = $"({parameterDefinitions[argumentIndex].ParameterType.GetCorrectCSharpTypeName()})"; // it's an object so we need to cast it to the right type

See PR dotnet#1228

-string cast = $"({Value.GetType().GetCorrectCSharpTypeName()})"; // it's an object so we need to cast it to the right type
+string cast = $"({parameterDefinitions[argumentIndex].ParameterType.GetCorrectCSharpTypeName()})"; // it's an object so we need to cast it to the right type

Would probably fix dotnet#2011

Outdated package references

Almost all of these package refs are outdated:

<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.4.3" />
<PackageReference Include="Iced" Version="1.8.0" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="1.1.126102" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="2.1.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="Perfolizer" Version="0.2.1" />
<PackageReference Include="System.Management" Version="4.5.0" />
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.10.0" />
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.61701" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.61" PrivateAssets="contentfiles;analyzers" />
</ItemGroup>
Current versions:

  <ItemGroup>
    <PackageReference Include="CommandLineParser" Version="2.8.0" />
    <PackageReference Include="Iced" Version="1.14.0" />
    <PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.226801" />
    <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
    <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
    <PackageReference Include="Perfolizer" Version="0.2.1" />
    <PackageReference Include="System.Management" Version="5.0.0" />
    <PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
    <PackageReference Include="System.ValueTuple" Version="4.5.0" />
    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
    <PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.236902" />
    <PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.71" PrivateAssets="contentfiles;analyzers" />
  </ItemGroup>

Noticed this as BDN wasn't reporting VM infos with .NET core builds because System.Management.ManagementObjectSearcher throws an exception that's silently eaten.
The outdated refs might cause some other side effects as well.
Don't know if they are kept for some backward compat.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.