gpt4 book ai didi

c# - 如何在 C# 中对性能优化进行单元测试?

转载 作者:IT王子 更新时间:2023-10-29 04:24:30 32 4
gpt4 key购买 nike

我在构建的一些搜索代码中使用了 Levenshtein 算法的优化版本。我有功能单元测试来验证算法是否返回正确的结果,但在这种情况下,算法的性能也非常重要。

我希望为项目添加一些测试范围,以便如果 future 的任何修改影响优化,它们将显示为失败测试 - 因为该算法是确定性的并且针对已知测试数据运行,这可能是详细为计算针对给定测试输入集执行的指令数。换句话说,我不打算使用计时器来衡量算法性能 - 我感兴趣的是实际测试算法的内部行为,而不仅仅是输出。

我有什么想法可以在 C#/.NET 4 中处理这个问题吗?

编辑:我不想只使用挂钟时间的原因是它会随着 CPU 负载和测试控制之外的其他因素而变化。例如,当构建服务器负载不足时,这可能会导致测试失败。作为已部署系统的一部分,挂钟监控。

编辑 2:这样想...当性能是关键要求时,您将如何应用红色->绿色->重构?

最佳答案

我将回答你问题的第三部分,因为我已经多次成功地做到了这一点。

how would you apply red->green->refactor when performance is a critical requirement?

  1. 针对您计划更改的内容以及可能因您的更改而变慢的其他方法,编写固定测试以捕获回归。
  2. 编写失败的性能测试。
  3. 提高性能,经常运行所有测试。
  4. 更新固定测试以更准确地固定性能。

编写固定测试

创建一个这样的辅助方法来为您想要固定的内容计时。

private TimeSpan Time(Action toTime)
{
var timer = Stopwatch.StartNew();
toTime();
timer.Stop();
return timer.Elapsed;
}

然后编写一个断言您的方法不花时间的测试:

[Test]
public void FooPerformance_Pin()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0));
}

当它失败时(在失败消息中显示实际耗时),用比实际时间略长的时间更新时间。重新运行,它将通过。对其他函数重复此操作,您的更改可能会影响其性能,最终得到类似这样的结果。

[Test]
public void FooPerformance_Pin()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0.8));
}
[Test]
public void BarPerformance_Pin()
{
Assert.That(Time(()=>fooer.Bar()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(6));
}

编写失败的性能测试

我喜欢将这种测试称为“诱饵测试”。这只是固定测试的第一步。

[Test]
public void FooPerformance_Bait()
{
Assert.That(Time(()=>fooer.Foo()), Is.LessThanOrEqualTo(TimeSpan.FromSeconds(0));
}

现在,致力于性能改进。每次尝试性改进后运行所有测试(固定和诱饵)。如果成功,您会在诱饵测试的失败输出中看到时间减少,并且您的固定测试都不会失败。

当您对改进感到满意时,为您更改的代码更新固定测试,并删除诱饵测试。

您现在如何处理这些测试?

最不需要担心的事情是用 Explicit 标记这些测试属性,并在您下次要检查性能时保留它们。

在工作范围的另一边,在 CI 中创建一个控制良好的子系统来运行这些类型的测试是监控性能回归的一种非常好的方法。根据我的经验,与实际故障相比,人们更担心它们“由于其他原因导致 CPU 负载而随机失败”。这种努力的成功更多地取决于团队文化,而不是您对环境进行控制的能力。

关于c# - 如何在 C# 中对性能优化进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15181358/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com