【发布时间】:2013-05-02 21:11:38
【问题描述】:
我注意到 C# 抖动产生的代码比 C++ 编译器慢得多,即使没有使用“托管开销”构造(例如带有检查索引的数组)。
为了量化它,我对以下简单循环进行了计时:
public static int count = 1000000000;
public static int Main()
{
int j = 0;
for (int i = 0; i < count; ++i)
{
j += (i % 2 == 0) ? ((i + 7) >> 3) : (i * 7);
}
return j;
}
这个循环需要 3.88 秒来执行(用 /o 编译)。使用 VC 2010 (-O2) 编译的等效循环需要 2.95 秒。
为了验证是否确实生成了劣质代码,我比较了机器代码:从 VC 编译器创建了一个列表 (/FAs),并将调试器附加到 C# 程序(循环完成后)。
确实,C++ 版本使用了一些巧妙的技巧。例如,为了避免代价高昂的乘以 7,有一个单独的寄存器,每次循环计数都会增加 7。 C# 版本每次都进行乘法 (imul)。还有其他区别。
我知道 C# jitter 在运行时编译代码的时间比 VC 在构建时要少得多。但是例如Java jitter 动态优化常用方法。 C# 似乎没有这样做。
我的问题是:是否有计划在未来的框架版本中改进 C# 抖动?
【问题讨论】:
-
Visual Studio RC 2012 with .NET 4.5 从昨天开始可供下载。下载它(它是免费的)并在那里运行相同的测试。
-
很久以前,我已经不再为抖动所做的新优化而屏住呼吸了。 MS 似乎认为它在那个部门已经足够好了。
-
@JonHanna 从 .NET 4 开始。3.5 有一些好东西,没想到太多,但在那之后 NGen 得到了所有的爱。
-
@harold 在 4.0 中完成尾调用消除的更大情况并非仅限 NGen。
-
您的测试经过精心挑选,以展示 C++ 比 C# 快的一种特定情况。我从未见过这种情况出现在我处理过的代码中,所以对我来说 JIT 用它做什么并不重要。如果您再次运行测试但专注于内存分配器(实际上几乎每个人都在使用它),我想您会发现结果大不相同。
标签: c# optimization jit