我需要检查某些 .NET API 的性能,因此我想到了这段代码。
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++) {
int res = (int) SOME .NET FUNCTION TO RUN;
}
sw.Stop();
double time = sw.Elapsed.TotalMilliseconds;
我再想想,我担心编译器会优化所有操作,因为 res
没有在任何地方使用。并且我修改了代码如下。
Stopwatch sw = Stopwatch.StartNew();
long sumIt = 0;
for (int i = 0; i < 1000; i++) {
int res = (int) SOME .NET FUNCTION TO RUN;
sumIt += res;
}
sw.Stop();
double time = sw.Elapsed.TotalMilliseconds;
value = (int) sumIt / 1000;
有趣的是,编译器似乎并没有优化我的第一个示例的操作。我使用 csc (Visual Studio) 和 mono 进行了测试。
我的问题来了。
- 将基准作为我的第一个示例是否安全?
- 难道 C# 编译器不够聪明,无法理解某些代码可以优化掉吗?或者,是否有任何编译器参数?
已添加
SOME FUNCTION TO RUN
实际上是 SOME .NET FUNCTION TO RUN
,我修改了 OP。
根据答案,C# 编译器似乎无法(或不会)优化操作,因为 .NET FUNCTION TO RUN
可能会产生副作用。
最佳答案
如果编译器 (JIT) 发现它没有副作用,它可能会优化整个函数调用。它可能需要能够内联函数来检测。
...
for (int i = 0; i < 1000; i++)
{
int res = (int) Func(i);
}
...
static int Func(int arg1)
{
return arg1 * arg1;
}
反汇编:
for (int i = 0; i < 1000; i++)
00000016 xor eax,eax
00000018 inc eax
00000019 cmp eax,3E8h
0000001e jl 00000018
}
关于用于基准测试目的的 C# 编译器优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6524090/