c# - <= 确实比 < 慢

标签 c# performance

我在 SO 上发现了一些关于 performance comparison of < and <= 的问题(这个被极度否决)我总是找到相同的答案,即两者之间没有性能差异。

我编写了一个用于比较的程序 ( not so working fiddle...copy to your machine to run it ),我在其中创建了两个循环 for (int i = 0; i <= 1000000000; i++ )for (int i = 0; i < 1000000001; i++ )用两种不同的方法。

我对每个方法都运行了 100 次;取耗时的平均值,发现循环为 <=运算符(operator)比使用 < 的运算符(operator)运行得慢运营商。

我多次运行该程序并且 <=总是需要更多的时间来完成。 我的结果 (im ms) 是:

3018.73, 2778.22

2816.87, 2760.62

2859.02, 2797.05

我的问题是:如果两者都不快,为什么我会看到结果有差异?我的程序有什么问题吗?

最佳答案

基准测试是一门艺术。您所描述的在物理上是不可能的,<= 和 < 运算符只是生成以完全相同速度执行的不同处理器指令。我稍微修改了你的程序,运行 DoIt 十次并从 for() 循环中删除两个零,这样我就不必永远等待:

x86 抖动:

Less Than Equal To Method Time Elapsed: 0.5
Less Than Method Time Elapsed: 0.42
Less Than Equal To Method Time Elapsed: 0.36
Less Than Method Time Elapsed: 0.46
Less Than Equal To Method Time Elapsed: 0.4
Less Than Method Time Elapsed: 0.34
Less Than Equal To Method Time Elapsed: 0.33
Less Than Method Time Elapsed: 0.35
Less Than Equal To Method Time Elapsed: 0.35
Less Than Method Time Elapsed: 0.32
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.32
Less Than Equal To Method Time Elapsed: 0.34
Less Than Method Time Elapsed: 0.32
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.31
Less Than Equal To Method Time Elapsed: 0.34
Less Than Method Time Elapsed: 0.32
Less Than Equal To Method Time Elapsed: 0.31
Less Than Method Time Elapsed: 0.32

x64 抖动:

Less Than Equal To Method Time Elapsed: 0.44
Less Than Method Time Elapsed: 0.4
Less Than Equal To Method Time Elapsed: 0.44
Less Than Method Time Elapsed: 0.45
Less Than Equal To Method Time Elapsed: 0.36
Less Than Method Time Elapsed: 0.35
Less Than Equal To Method Time Elapsed: 0.38
Less Than Method Time Elapsed: 0.34
Less Than Equal To Method Time Elapsed: 0.33
Less Than Method Time Elapsed: 0.34
Less Than Equal To Method Time Elapsed: 0.34
Less Than Method Time Elapsed: 0.32
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.35
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.42
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.31
Less Than Equal To Method Time Elapsed: 0.32
Less Than Method Time Elapsed: 0.35

您从中获得的唯一真实信号是第一个 DoIt() 的缓慢执行,这在您的测试结果中也可见,这是抖动开销。最重要的信号是嘈杂。两个循环的中值大致相等,标准偏差相当大。

否则,当您进行微优化时,您总是会收到那种信号,代码的执行不是很确定。除了通常很容易消除的 .NET 运行时开销之外,您的程序并不是唯一在您的计算机上运行的程序。它必须共享处理器,只是 WriteLine() 调用已经产生影响。由 conhost.exe 进程执行,在您的测试代码进入下一个 for() 循环时与您的测试同时运行。机器上发生的所有其他事情、内核代码和中断处理程序也轮到它们了。

codegen 可以发挥作用,例如,您应该做的一件事就是交换两个调用。处理器本身通常非常不确定地执行代码。处理器缓存的状态以及分支预测逻辑收集了多少历史数据非常重要。

当我进行基准测试时,我认为 15% 或更少的差异在统计上不显着。寻找小于那个的差异是相当困难的,你必须非常仔细地研究机器代码。分支目标未对齐或变量未存储在处理器寄存器中等愚蠢的事情可能会对执行时间产生重大影响。这不是您可以解决的问题,抖动没有足够的旋钮来调整。

关于c# - <= 确实比 < 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29702328/

相关文章:

c# - 无法在 SQL Management Studio 中连接

c# - 如何获取控制台应用程序窗口的句柄

c# - Web 服务日期时间参数不接受英国格式 DD/MM/YYYY

javascript - 带有客户端凭证流的 Swashbuckle OAuth2 授权

javascript - img 标签元素与带有背景图片的 div 之间的性能差异?

javascript - 为什么 node.js 比 Google Chrome 慢得多?

javascript - 同时连接太多字符串导致前端长时间阻塞,如何优化?

c# - 在我的 webapi 中没有获取信息级别日志

python - 并行读取大文件?

javascript - 在 JavaScript 和 jQuery 中使用委托(delegate)事件处理程序是否存在性能缺陷?