C#优化表达式折叠观察值 我已经做C++开发人员很多年了,以前切换到C语言。最近,我开始使用dotPeek来恢复一些旧代码。我惊讶地看到反编译器中的代码看起来如此未优化。我开始编写一些代码,希望编译器能够进行表达式折叠,结果让我大吃一惊。我想和大家分享我的观察结果,看看大家对我为什么看到我看到的结果有什么评论

C#优化表达式折叠观察值 我已经做C++开发人员很多年了,以前切换到C语言。最近,我开始使用dotPeek来恢复一些旧代码。我惊讶地看到反编译器中的代码看起来如此未优化。我开始编写一些代码,希望编译器能够进行表达式折叠,结果让我大吃一惊。我想和大家分享我的观察结果,看看大家对我为什么看到我看到的结果有什么评论,c#,optimization,expression,folding,C#,Optimization,Expression,Folding,编译器选项已在..上优化。NET版本4.5 首先,我将分享我预期的结果: Console.Write(1 + 1 + 1); turned into Console.Write(3); Console.Write ("a" + "b" + "c"); turned into Console.Write("abc"); 下面是我感到惊讶的地方: string a = "aaaaa"; string b = "aaaaa"; Console.Write(b + a); 我希望编译器将这个

编译器选项已在..上优化。NET版本4.5

首先,我将分享我预期的结果:

Console.Write(1 + 1 + 1);  turned into Console.Write(3);  
Console.Write ("a" + "b" + "c"); turned into Console.Write("abc");
下面是我感到惊讶的地方:

string a = "aaaaa";
string b = "aaaaa";

Console.Write(b + a);
我希望编译器将这个表达式折叠为:output.Write(“aaaaaaaa”);或至少输出。写入(a+a);两个都没有。它保留了原作。令人惊讶的是,编译器没有注意到重复的文本,并且两次引用它的单个副本,或者将常量折叠在一起。你可能会说我没有加“const”。(当我这样做时,编译器确实折叠了表达式,并删除了所有常量)。变量是局部变量,仅在这一个地方使用。编译器应该注意到这一点,并正确地将表达式折叠在一起,而不使用“const”属性

我对int做了完全相同的实验。结果几乎相同:当我使用const int时,它正确折叠。当我删除“const”属性时

int c = 1, d = 1, e = 1;
Console.Write(c + d + e);
导致:

int num1 = 1;
int num2 = 1;
int num3 = 1;
int num4 = num2;
Console.Write(num1 + num4 + num3);
这完全是巴扎。我无法解释这一点。编译器编写了更糟糕的代码。
在表达式折叠方面,C++编译器似乎做得更好。

你不考虑JIT编译器。从.NET程序集生成的是IL,当每个方法被命中时,它会被进一步编译成本机程序集。这就是“真正的”优化发生的地方,它可能会正确地折叠变量。这看起来很奇怪。是否有任何代码在int情况下没有显示给我们?您是如何获得最后一段代码的?在字符串声明前面加上
const
,应该这样做。变量不被视为常量,其中的“内联”字符串常量是常量。我很确定dotPeek在最后一个示例中从IL生成了一个不正确的映射。不是“可怕的错误”,只是不完全是代码在做什么。你能分享生成的IL代码吗?