在c#中添加字符串,编译器如何做到这一点?

Car*_*Jr. 6 c# string process string-concatenation

A = string.Concat("abc","def") 

B = "abc" + "def"
Run Code Online (Sandbox Code Playgroud)

A与B.

最近我很困惑为什么很多人会说,与B相比,A的处理速度要快得多.但是,他们只会说因为有人这么说或者因为它就是这样.我想我可以从这里听到更好的解释.

编译器如何处理这些字符串?

谢谢!

Eri*_*ert 12

当我加入C#编译器团队时,我做的第一件事就是重写了字符串连接的优化器.美好时光.

如前所述,常量字符串的字符串连接在编译时完成.非常量字符串做一些奇特的东西:

a + b --> String.Concat(a, b)
a + b + c --> String.Concat(a, b, c)
a + b + c + d --> String.Concat(a, b, c, d)
a + b + c + d + e --> String.Concat(new String[] { a, b, c, d, e })
Run Code Online (Sandbox Code Playgroud)

这些优化的好处是String.Concat方法可以查看所有参数,确定它们的长度之和,然后创建一个可以容纳所有结果的大字符串.

这是一个有趣的.假设您有一个返回字符串的方法M:

s = M() + "";
Run Code Online (Sandbox Code Playgroud)

如果M()返回null,则结果为空字符串.(null + empty为空.)如果M不返回null,则空字符串的连接不会改变结果.因此,这实际上是优化的,因为根本不是对String.Concat的调用!它成为了

s = M() ?? ""
Run Code Online (Sandbox Code Playgroud)

干净,嗯?


Bot*_*000 5

在C#中,字符串的加法运算符只是String.Concat的语法糖.您可以通过在反射器中打开输出组件来验证.

另外需要注意的是,如果代码中有字符串文字(或常量),例如在示例中,编译器甚至会将其更改为B = "abcdef".

但是,如果你使用String.Concat两个字符串文字或常量,仍然会调用String.Concat,跳过优化,因此+操作实际上会更快.

所以,总结一下:

stringA + stringB成为String.Concat(stringA, stringB).
"abc" + "def"变得"abcdef"
String.Concat("abc", "def")保持不变

我必须尝试的其他东西:

在C++/CLI中,"abc" + "def" + "ghi"实际上是转换为String.Concat(String.Concat("abc", "def"), "ghi")

  • 没有两个字符串文字它不会:`B`将直接设置为"abcdef". (3认同)