标签: benchmarkdotnet

如果性能下降太多,是否可以使用 Benchmark.NET 使 CI 构建“失败”?

我有单元测试。如果其中之一失败,我的构建就会失败。

我想将相同的原则应用于性能。我有一系列针对通过库的几个热路径的微基准测试。根据经验,这些领域的放缓对图书馆的整体性能产生了不成比例的影响。

如果有某种方法可以有一些“性能构建”的概念,如果性能回归太显着,它可能会失败,那就太好了。

我曾考虑过不得超过的硬编码阈值。就像是:

Assert.IsTrue(hotPathTestResult.TotalTime <= threshold)

但是将其与绝对值挂钩是硬件和环境相关的,因此很脆弱。

有没有人实现过这样的东西?微软为 Kestrel 做了什么?

performance-testing benchmarkdotnet

6
推荐指数
1
解决办法
923
查看次数

C#for-loop和Array.Fill之间的性能差异

我使用以下方法实现了以下基准BenchmarkDotNet:

public class ForVsFillVsEnumerable
{
    private bool[] data;

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

    [GlobalSetup]
    public void Setup()
    {
        data = new bool[N];
    }

    [Benchmark]
    public void Fill()
    {
        Array.Fill(data, true);
    }

    [Benchmark]
    public void For()
    {           
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = true;
        }
    }

    [Benchmark]
    public void EnumerableRepeat()
    {
        data = Enumerable.Repeat(true, N).ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17763.195 (1809/October2018Update/Redstone5)
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 …
Run Code Online (Sandbox Code Playgroud)

.net c# arrays performance benchmarkdotnet

6
推荐指数
1
解决办法
308
查看次数

是否可以使用 #if NET6_0_OR_GREATER 从 BenchmarkDotNet 运行中排除基准测试方法?

假设您正在编写一些与 BenchmarkDotNet 一起使用的基准测试,这些基准测试多目标为net48net6.0,并且这些基准测试之一只能针对该net6.0目标进行编译。

显而易见的事情是使用类似的方法从构建中排除该特定基准net48

#if NET6_0_OR_GREATER

[Benchmark]
public void UsingSpan()
{
    using var stream = new MemoryStream();
    writeUsingSpan(stream, _array);
}

static void writeUsingSpan(Stream output, double[] array)
{
    var span  = array.AsSpan();
    var bytes = MemoryMarshal.AsBytes(span);

    output.Write(bytes);
}

#endif // NET6_0_OR_GREATER
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,并且它不起作用的方式取决于TargetFrameworks项目文件中的属性中指定的目标的顺序。

如果您订购框架,那么net6.0首先<TargetFrameworks>net6.0;net48</TargetFrameworks>(在上面的示例中)该UsingSpan()方法将包含在两个目标中,导致目标net48和输出出现 BenchmarkDotNet 构建错误,如下所示:

|            Method |                Job |            Runtime |       Mean |     Error |    StdDev |
|------------------ |------------------- |------------------- |-----------:|----------:|----------:|
| …
Run Code Online (Sandbox Code Playgroud)

c# multitargeting benchmarkdotnet

6
推荐指数
1
解决办法
2223
查看次数

如何在 BenchmarkDotNet 中使用 DependencyInjection?

我想在我现在正在使用的一些遗留代码上使用 BenchmarkDotNet。它是用 C# Net462 编写的。这是一个庞大、古老且复杂的系统,我想对某些特定类中的一些方法进行基准测试。这些类使用依赖注入,我不确定如何做到这一点。到目前为止我看到的所有示例都没有使用任何依赖注入。

有人有什么想法或例子我可以看一下吗?

非常感谢。

dependency-injection .net-4.6 benchmarkdotnet

6
推荐指数
1
解决办法
3846
查看次数

如何在 BenchmarkDotNet 中对同一非 NuGet 库的两个不同版本进行基准测试?

我正在尝试使用 BenchmarkDotNet 为库准备性能回归测试。这要求我将相同的测试与旧(稳定)版本的库进行比较。现在,可以选择为作业提供不同版本的 NuGet 包。似乎没有一个选项可以代替引用不同的程序集。

我尝试过自定义构建配置:

  <ItemGroup Condition="'$(Configuration)' == 'Baseline'">
    <Reference Include="MyAssembly">
      <HintPath>lib\baseline\MyAssembly.dll</HintPath>
    </Reference>
  </ItemGroup>

  <ItemGroup Condition="'$(Configuration)' != 'Baseline'">
    <Reference Include="MyAssembly">
      <HintPath>lib\current\MyAssembly.dll</HintPath>
    </Reference>
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

但是当尝试通过 BenchmarkDotNet 使用这些配置时

    public static void Main(string[] args) {
      var summary = BenchmarkRunner.Run(typeof(Program).Assembly,
        DefaultConfig.Instance
          .With(Job.Default.WithCustomBuildConfiguration("Baseline"))
          .With(Job.Default.WithCustomBuildConfiguration("Current")));
    }
Run Code Online (Sandbox Code Playgroud)

我收到构建错误,表明该程序集根本没有被引用。BenchmarkDotNet 还有助于清除它创建的任何临时工件,因此我什至无法查看生成的项目文件来弄清楚它的外观。

这里唯一的解决方法是将库包装在 NuGet 包中吗?或者在(对于这种情况看似稀疏的)文档中是否有我忽略的东西?

这个问题似乎与我遇到的构建错误隐约相关。

benchmarkdotnet

5
推荐指数
1
解决办法
812
查看次数

为什么分配的内存比预期的多?

我正在使用 BenchmarkDotNet 及其 MemoryDiagnoser 功能。

考虑以下基准:

[Benchmark]
public void Dummy()
{
   var buffer = new byte[1];
}
Run Code Online (Sandbox Code Playgroud)

我希望它恰好分配 1 个字节。

但是基准测试结果显示总共分配了 32 个字节。怎么来的?我觉得这很有误导性。

| Method |     Mean |     Error |    StdDev |   Median | Ratio | Rank |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|------- |---------:|----------:|----------:|---------:|------:|-----:|-------:|------:|------:|----------:|
|  Dummy | 4.486 ns | 0.1762 ns | 0.5196 ns | 4.650 ns |  1.00 |    1 | 0.0038 |     - |     - |      32 B |

                                                                                      why …
Run Code Online (Sandbox Code Playgroud)

c# memory benchmarkdotnet

5
推荐指数
2
解决办法
149
查看次数

DI容器泄漏内存或BenchmarksDotNet MemoryDiagnoser提供不准确的测量?

介绍

我们正试图捕获潜在的内存泄漏BenchmarksDotNet.

为了简单的例子,这里是一个简单的TestClass:

public class TestClass 
{
    private readonly string _eventName;

    public TestClass(string eventName)
    {
        _eventName = eventName;
    }

    public void TestMethod() =>
        Console.Write($@"{_eventName} ");
}
Run Code Online (Sandbox Code Playgroud)

我们正在通过NUnit测试实现基准测试netcoreapp2.0:

[TestFixture]
[MemoryDiagnoser]
public class TestBenchmarks
{
    [Test]
    public void RunTestBenchmarks() =>
        BenchmarkRunner.Run<TestBenchmarks>(new BenchmarksConfig());

    [Benchmark]
    public void TestBenchmark1() =>
        CreateTestClass("Test");

    private void CreateTestClass(string eventName)
    {
        var testClass = new TestClass(eventName);
        testClass.TestMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试输出包含以下摘要:

         Method | Mean | Error | Allocated |
--------------- |-----:|------:|----------:|
 TestBenchmark1 |   NA | …
Run Code Online (Sandbox Code Playgroud)

memory-leaks autofac tinyioc benchmarkdotnet

4
推荐指数
1
解决办法
167
查看次数

我应该创建单独的基准项目吗?

我想使用 BenchmarkDotNet 库测量控制台应用程序中某些方法的性能。

问题是:我应该在解决方案中创建一个单独的项目,在其中复制我感兴趣的测量方法并在那里进行测量,还是应该将测量所需的所有属性添加到现有项目中?

这里的约定是什么?

.net benchmarkdotnet

4
推荐指数
1
解决办法
1174
查看次数

在发布模式下关闭调试器

我已将“构建”设置为“发布”模式。

在此输入图像描述

我正在运行我的.NET Core 3.1控制台应用程序Benchmark DotNet。但它告诉我,

摘要 -> 基准测试是使用附加的调试器执行的

如何在构建模式下完全关闭调试器Release

c# visual-studio benchmarkdotnet

3
推荐指数
1
解决办法
1974
查看次数

BenchmarkDotNet 面对奇怪的解决方案结构时无法找到测试

我在 BenchmarkDotNet 上遇到问题,很难解决

这是我的项目结构:

- 
    | - Infrastructure
    |        |
    |        | - TestsBenchmark
    |        | - MyInfra.sln
    | - src
            | - Tests
            | - MyProduct.sln
Run Code Online (Sandbox Code Playgroud)

TestsBenchmark引用Tests并且只有这行代码:

BenchmarkSwitcher.FromAssembly(typeof(BasicTests).Assembly).RunAll();
Run Code Online (Sandbox Code Playgroud)

但是当我通过它运行dotnet run -c Release它时它会抛出

// Generate Exception: Unable to find Tests in ...\Infrastructure and its subfolders. Most probably the name of output exe is different than the name of the .(c/f)sproj

以前我的项目结构是这样的:

- 
    | - src
            | - Tests
            | - TestsBenchmark
Run Code Online (Sandbox Code Playgroud)

一切正常

复制步骤(手动),它重新创建文件夹结构、项目、项目关系、解决方案并添加 nuget。在某个空文件夹中的例如 powershell …

c# benchmarkdotnet

3
推荐指数
1
解决办法
1606
查看次数