假设我有这样的东西:
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
intod * 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
intod * 0.5
?
是的。在那种情况下,这些值可以精确地用二进制表示,因为 1/2 在底部有一个很小的 2 的幂。
抖动还可以改变整数除法和乘法,例如 x / 2
或 x * 2
进入x >> 1
或 x << 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/