经常这样我发现自己对小块代码进行基准测试,看看哪个实现最快.
我经常看到基准测试代码没有考虑到jitting或垃圾收集器的评论.
我有以下简单的基准测试功能,我已经慢慢演变了:
static void Profile(string description, int iterations, Action func) {
// warm up
func();
// clean up
GC.Collect();
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < iterations; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
Run Code Online (Sandbox Code Playgroud)
用法:
Profile("a descriptions", how_many_iterations_to_run, () =>
{
// ... code being profiled
});
Run Code Online (Sandbox Code Playgroud)
这个实现是否有任何缺陷?是否足以表明实现X比Z迭代实现Y更快?您能想出任何可以改善这种情况的方法吗?
编辑 很明显,基于时间的方法(与迭代相反)是首选,是否有人有任何实施时间检查不会影响性能?
为什么要注释这个for循环的前两行,并在42%的加速时取消注释第三个结果?
int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
var isMultipleOf16 = i % 16 == 0;
count += isMultipleOf16 ? 1 : 0;
//count += i % 16 == 0 ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
在时序背后是非常不同的汇编代码:循环中的13对7指令.该平台是运行.NET 4.0 x64的Windows 7.启用了代码优化,测试应用程序在VS2010之外运行.[ 更新: Repro项目,对验证项目设置很有用.]
消除中间布尔值是一个基本的优化,是我1980年代龙书中最简单的一个.在生成CIL或JITing x64机器代码时,如何不应用优化?
有没有"真正的编译器,我希望你优化这段代码,请"切换?虽然我同情过早优化类似于对金钱的热爱的情绪,但我可以看到试图描述一个复杂算法的挫败感,这个算法在整个惯例中分散.你可以通过热点工作,但没有暗示更广泛的温暖区域可以通过手动调整我们通常认为理所当然的编译器来大大改善.我当然希望我在这里遗漏一些东西.
更新: x86也会出现速度差异,但取决于方法即时编译的顺序.请参阅为什么JIT订单会影响性能?
汇编代码(根据要求):
var isMultipleOf16 = i % 16 == 0;
00000037 mov eax,edx
00000039 and eax,0Fh
0000003c xor ecx,ecx …Run Code Online (Sandbox Code Playgroud) 我正在通过Kip Irvine的"x86处理器的汇编语言,第六版"工作,我真的非常喜欢它.
我刚才读到了以下段落中的NOP助记符:
"It [NOP] is sometimes used by compilers and assemblers to align code to
even-address boundaries."
Run Code Online (Sandbox Code Playgroud)
给出的例子是:
00000000 66 8B C3 mov ax, bx
00000003 90 nop
00000004 8B D1 mov edx, ecx
Run Code Online (Sandbox Code Playgroud)
然后该书指出:
"x86 processors are designed to load code and data more quickly from even
doubleword addresses."
Run Code Online (Sandbox Code Playgroud)
我的问题是:原因是因为对于本书所指的x86处理器(32位),CPU的字大小是32位,因此它可以将NOP中的指令拉入并处理它们走 ?如果是这种情况,我假设一个字长为四字的64位处理器会用一个假设的5字节代码和一个nop来做到这一点?
最后,在我编写代码之后,我是否应该通过NOP进行正确的对齐以优化它,或者编译器(MASM,在我的情况下),为我做这个,正如文本似乎暗示的那样?
谢谢,
斯科特