编译器在优化字符串连接方面有多聪明。

时间:2013-06-26 14:04:23

标签: c# .net clr compiler-optimization string-concatenation

我很好奇C#编译器如何处理下面的两个语句:

String text = "abcdefghijklmnopqrstuvwxyz";
text = text.Substring( 0, 15 );
text = text + "...";

VS

String text = "abcdefghijklmnopqrstuvwxyz";
text = text.Substring( 0, 15 ) + "...";

结果当然是一样的,但是连接运算符是否在第二次设置中更好地优化了代码?

在两种情况下,你最终都会为堆栈上的字符串分配4个分配,或者第二种情况只分配3个吗?

在阅读一些代码时我只是一个随机的问题。

2 个答案:

答案 0 :(得分:10)

首先,首先不在堆栈上分配字符串。字符串在堆上。

其次,两种情况都有四种分配方式。我很好奇你认为哪一个可能会消失。

巧合的是,本周这是我博客的主题。请参阅this article,了解有关此主题的更多信息。

答案 1 :(得分:2)

我拿了你的代码并在一个简单的控制台应用程序中编译它。然后,我检查了IL(使用ILSpy)。在调试或发布模式下都没有进行优化。

在这种情况下,代码可能很简单,编译器没有进行任何优化。但是,更复杂的版本可能会产生不同的结果。

另外,请注意两个示例之间的差异很小。在这两种情况下,运行时最终会生成四个不同的字符串对象。在第一个示例中,对变量的赋值仅执行两次,而在第二个示例中,赋值执行三次。但是,无论如何都会创建四个字符串。它们如下:

  • “ABCDEFGHIJKLMNOPQRSTUVWXYZ”
  • “abcdefghijklmno”(来自子串)
  • “...”
  • “abcdefghijklmno ......”(来自连接)

在这两种情况下,前三个字符串几乎立即符合垃圾收集条件。我猜测编译器没有看到任何改进你所拥有的重要方法。