我在 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/