beb*_*ebo 3 c# optimization compiler-optimization
为什么编译器会优化我的代码?
我有2个功能:
public void x1() {
x++;
x++;
}
public void x2() {
x += 2;
}
public void x3() {
x = x + 2;
}
public void y3() {
x = x * x + x * x;
}
Run Code Online (Sandbox Code Playgroud)
这是我在发布模式下编译后可以看到的ILSpy:
// test1.Something
public void x1()
{
this.x++;
this.x++;
}
// test1.Something
public void x2()
{
this.x += 2;
}
// test1.Something
public void x3()
{
this.x += 2;
}
// test1.Something
public void y3()
{
this.x = this.x * this.x + this.x * this.x;
}
Run Code Online (Sandbox Code Playgroud)
x2和x3可能没问题.但是为什么x1没有针对相同的结果进行优化?没有理由保持两步增量?为什么y3不是x=2*(x*x)?那不应该快x*x+x*x吗?
这导致了这个问题?如果没有这么简单的事情,C#编译器会进行什么样的优化?
当我阅读有关编写您经常听到的代码的文章时,将其写为可读,编译器将完成其余的工作.但在这种情况下,编译器几乎什么也没做.
再添一个例子:
public void x1() {
int a = 1;
int b = 1;
int c = 1;
x = a + b + c;
}
Run Code Online (Sandbox Code Playgroud)
并使用ILSpy:
// test1.Something
public void x1()
{
int a = 1;
int b = 1;
int c = 1;
this.x = a + b + c;
}
Run Code Online (Sandbox Code Playgroud)
为什么不是这个.= 3?
如果不假设变量x不会与运行方法同时访问,则编译器无法执行此优化.否则,可能会以可检测的方式更改方法的行为.
考虑this从两个线程同时访问引用的对象的情况.胎面A反复设定x为零; 线程B反复调用x1().
如果编译器优化x1为的等效x2,两个观察的状态x后,您的实验将是0和2:
A完成之前B,你得到2B完成之前A,你得到0如果在中间A先发制人B,你仍然会得到一个2.
然而,最初的版本中x1允许三种结果:x最终会成为0,1或2.
A完成之前B,你得到2B完成之前A,你得到0B在第一个增量之后被抢占,那么A结束,然后B运行完成,你得到1.