c# - C# 编译器或 Jitter 会优化这些类型的算术运算吗?

标签 c# .net optimization compiler-construction jit

假设我有这样的东西:

for (int i = 0; i < 1001; i++)
{
    double step = i / 1000.0;

    // do some math here
}

基本转向:

double step = i / 1000.0;

进入这个:

double step = i * 0.001;

我不确定是否可以在不改变程序结果的情况下进行这种改变,但想知道 C# 编译器或抖动是否会做这样的事情?如果不是,为什么?我认为这不值得,或者他们还没有添加此优化。

最佳答案

让我们把它分解成几个问题:

Can the jitter legally change d / 1000.0 into d * 0.001?

不,因为这两个计算给出不同的结果。请记住, float 是二进制小数,而不是小数; 0.001 作为 double 不完全等于 1/1000,正如 0.333333333 作为 double 不完全等于 1/3。0.001 是最接近 1/1000 的分数,可以用 52 个二进制位表示。因此存在 x/1000.0 不等于 x * 0.001 的值。

Can the jitter legally change d / 2.0 into d * 0.5?

是的。在那种情况下,这些值可以精确地用二进制表示,因为 1/2 在底部有一个很小的 ​​2 的幂。

抖动还可以改变整数除法和乘法,例如 x / 2x * 2进入x >> 1x << 1 .

Does the jitter actually do so when it is legal?

我不知道。试试吧!

您要做的是编译“retail”程序,然后不在调试器中启动它并运行它,直到您知道相关代码已被编译。然后附加调试器并检查 jitted 代码。如果抖动知道附加了调试器,它会生成更糟糕的代码,因为它正在尝试生成更易于调试的代码。

I assume either it's not worth it or they didn't add this optimization yet.

对于从除法到乘法的情况,您假设乘法比除法快。现代芯片在这两方面都非常出色。虽然除法通常确实需要更多的位操作,但这种差异可能可以忽略不计。

关于c# - C# 编译器或 Jitter 会优化这些类型的算术运算吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8652181/

相关文章:

c# - 在 C# 中动态加载非托管 OCX

c# - 将文件名保存为变量

c# - LINQ Group by 并具有 where 子句

.net - Cruise Control .Net 不显示 Nant 构建错误

python - Numpy 2D 点运算、索引和迭代。如何优化?

c# - 使用反射通过从 setter 调用的方法获取属性的属性

c# - 在 .msi 安装程序中包装 C# 应用程序

c# - 项目管理: Implementing custom errors in VS compilation process

c++ - 更快的文件操作 C++

javascript - 如何限制else语句? - Javascript 游戏