gpt4 book ai didi

C# 编译器优化

转载 作者:行者123 更新时间:2023-11-30 13:36:38 26 4
gpt4 key购买 nike

为什么编译器要优化我的代码?

我有两个功能:

public void x1() {
x++;
x++;
}
public void x2() {
x += 2;
}
public void x3() {
x = x + 2;
}
public void y3() {
x = x * x + x * x;
}

这就是我在 Release模式下编译后使用 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;
}

x2 和 x3 可能没问题。但是为什么 x1 没有优化到相同的结果呢?没有理由保持 2 步增量?为什么 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;
}

并使用 ILSpy:

// test1.Something
public void x1()
{
int a = 1;
int b = 1;
int c = 1;
this.x = a + b + c;
}

为什么不是this.x = 3?

最佳答案

如果不假设变量 x 未与您的运行方法同时访问,则编译器无法执行此优化。否则,它可能会以可检测的方式改变您的方法的行为。

考虑以下情况:this 引用的对象被两个线程同时访问。 Tread A 重复设置 x 为零;线程 B 重复调用 x1()

如果编译器将 x1 优化为等同于 x2,则在您的实验之后 x 的两个可观察状态将是 02:

  • 如果 AB 之前完成,您将得到 2
  • 如果 BA 之前完成,您将得到 0

如果 A 在中间抢占 B,您仍然会得到 2

但是,x1 的原始版本允许三种结果:x 可以最终为 01,或 2

  • 如果 AB 之前完成,您将得到 2
  • 如果 BA 之前完成,您将得到 0
  • 如果 B 在第一次增量后被抢占,然后 A 完成,然后 B 运行完成,你得到 1

关于C# 编译器优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31731144/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com