【发布时间】:2011-09-25 07:54:27
【问题描述】:
我需要检查一些 .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 可能有副作用。
【问题讨论】:
-
如果 SOMEFUNCION 有副作用怎么办?您不使用它的返回值这一事实并不意味着它可以被丢弃。从理论上讲,编译器可以分析函数(以及该函数中的任何函数,...),但我认为这不切实际,我不认为它这样做。
-
我在过去编写一些基准测试时也想知道这一点。我还没有遇到一个结论性的声明,但似乎编译器不会优化对驻留在另一个程序集中的方法(也包括属性获取器,顺便说一句)的任何调用。
标签: c# .net optimization profiling benchmarking