用于基准测试目的的 C# 编译器优化

标签 c# .net optimization profiling benchmarking

我需要检查某些 .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/

相关文章:

c# - DEBentityValidationException 不是 "cleared"

c# - Websocket 服务器 : onopen function on the web socket is never called

c# - 在 variablesizedwrapgrid 代码后面设置 TextBlock 的宽度和高度无法正确显示

c - 如何使用 SSE-intrinsics 优化 C 代码以实现打包的 32x32 => 64 位乘法,并将这些结果的一半解包为(Galois Fields)

AMPL 数据文件的 Python 解析器

javascript - 快速(占用空间少)的 JavaScript 时钟

c# - 传递无效主机名时 NTP 查询需要很长时间

c# - 用户控件中具有 CompositeCollection 的 WPF ComboBox 不起作用 : SelectedIndex set to -1

c# - 如何使用构造函数初始化列表?

c# - 定义实现泛型的接口(interface)依赖