BenchmarkDotNet InProcessEmitToolchain完整示例

14
我第一次接触BenchmarkDotNet和基准测试。由于我们工作笔记本的杀毒软件限制,我似乎无法使用正常的BenchmarkRunner来运行基准测试,因此我尝试使用InProcessEmitToolchain,具体使用方法可以在这里找到。然而,在这些示例和这里列出的示例中,我看不到实际触发基准测试的应用程序入口点,我阅读文档也没找到有用的信息。
有没有人能够提供一个完整的使用InProcessEmitToolchain和/或jobs(任务)的示例,并解释如何结合应用程序入口点运行测试?
4个回答

17

我也曾遇到过Windows Defender拦截BenchmarkDotNet的问题。不过,我找到了如何更改工具链设置的方法,尽管我不得不使用InProcessNoEmitToolchain,因为InProcessEmitToolchain也被阻止了。

以下示例实际上并没有触发杀毒软件,但它展示了如何定义要使用哪个工具链:

[Program.cs]

using BenchmarkDotNet.Running;
using Benchmarks;

_ = BenchmarkRunner.Run<MaterializeTest>();

[MaterializeTest.cs]

using BenchmarkDotNet.Attributes;

namespace Benchmarks;

[Config(typeof(AntiVirusFriendlyConfig))]
[MemoryDiagnoser]
public class MaterializeTest
{
    IEnumerable<int> _sequence;

    [Params(10, 100, 1000, 10000)]
    public int _size;

    [GlobalSetup]
    public void Setup()
    {
        _sequence = Enumerable.Range(0, _size).Select(i => Random.Shared.Next());
    }

    [Benchmark]
    public IReadOnlyList<int> ToList() => _sequence.ToList();

    [Benchmark]
    public IReadOnlyList<int> ToArray() => _sequence.ToArray();
}

[AntiVirusFriendlyConfig.cs]

using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.InProcess.NoEmit;

namespace Benchmarks;

public class AntiVirusFriendlyConfig : ManualConfig
{
    public AntiVirusFriendlyConfig()
    {
        AddJob(Job.MediumRun
            .WithToolchain(InProcessNoEmitToolchain.Instance));
    }
}

[Benchmarks.csproj]

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
  </ItemGroup>
</Project>

1
我不是楼主,但这篇文章给了我解决同样问题所需的信息。谢谢。 - Niya
1
这对我也没有用。 - Mark Good

6
您可以使用您喜欢的工具链来调整配置:
var config = DefaultConfig.Instance
    .AddJob(Job
         .MediumRun
         .WithLaunchCount(1)
         .WithToolchain(InProcessEmitToolchain.Instance));

或者,另一种选择是:
var config = DefaultConfig.Instance
    .AddJob(Job
         .MediumRun
         .WithLaunchCount(1)
         .WithToolchain(InProcessNoEmitToolchain.Instance));

并将其传递给Run方法(在Andreas Warberg的程序基础上构建)

_ = BenchmarkRunner.Run<MaterializeTest>(config);

2

我最终无法通过使用InProcesNoEmitToolchain解决这个问题 - 我们的AV软件太顽固了。我通过让我们的IT人员在AV软件中添加白名单条目来解决这个问题,以便我们可以运行基准测试。


2
我遇到了一个问题,测试的应用程序组件太慢了;为了解决这个问题(错误消息是“运行时间过长。最好使用独立的工具链来进行长时间运行的基准测试”),我使用了上面其他答案提供的指导,并对其进行了扩展,具体如下:
public class MediumConfig : ManualConfig
{
    public MediumConfig()
    {
        AddJob(
               Job.MediumRun
                  .WithToolchain(InProcessNoEmitToolchain.Instance)
                  .WithStrategy(BenchmarkDotNet.Engines.RunStrategy.Throughput)
              )
            .WithOptions(ConfigOptions.DisableOptimizationsValidator);
    }
}

配置然后按照通常的方式应用:
[Config(typeof(MediumConfig))]
public class MyBenchmarkClassThatComparesALongRunningSetOfThings
{
    // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接