字符串连接性能的差异

我知道你在连接字符串时应该使用StringBuilder ,但我只是想知道连接字符串变量和字符串文字是否有区别。 那么,构建s1,s2和s3的性能是否存在差异?

 string foo = "foo"; string bar = "bar"; string s1 = "foo" + "bar"; string s2 = foo + "bar"; string s3 = foo + bar; 

在您出现的情况下,实际上最好在字符串类上使用连接运算符。 这是因为它可以预先计算字符串的长度并分配缓冲区一次,并将内存快速复制到新的字符串缓冲区中。

这是连接字符串的一般规则。 当你想要连接在一起的一定数量的项目(无论是2还是2000等)时,最好只使用连接运算符将它们连接起来,如下所示:

 string result = s1 + s2 + ... + sn; 

在您的特定情况下应该注意s1:

 string s1 = "foo" + "bar"; 

编译器看到它可以在这里优化字符串文字的串联,并将上面的内容转换为:

 string s1 = "foobar"; 

注意,这仅适用于将两个字符串文字连接在一起。 所以,如果你这样做:

 string s2 = foo + "a" + bar; 

然后它没有什么特别的(但它仍然调用Concat并预先计算长度)。 但是,在这种情况下:

 string s2 = foo + "a" + "nother" + bar; 

编译器会将其转换为:

 string s2 = foo + "another" + bar; 

如果你连接的字符串数是可变的(例如,你事先不知道它有多少元素的循环),那么StringBuilder是连接这些字符串的最有效方式,因为你将永远必须重新调用缓冲区以考虑要添加的新字符串条目(其中您不知道还剩多少)。

编译器可以在编译时连接文字,因此“foo”+“bar”直接编译为“foobar”,并且不需要在运行时执行任何操作。

除此之外,我怀疑是否有任何显着差异。

你的“知识”是不正确的。 在连接字符串时, 有时应该使用StringBuilder 。 特别是,当你无法在一次攻击中执行连接时,你应该这样做。

在这种情况下,代码编译为:

 string foo = "foo"; string bar = "bar"; string s1 = "foobar"; string s2 = String.Concat(foo, "bar"); string s3 = String.Concat(foo, bar); 

使用StringBuilder会降低任何效率 – 特别是它会将s1的串联从编译时推送到执行时。 对于s2s3它会强制创建一个额外的对象( StringBuilder ),也可能会分配一个不必要的大的string

我有一篇文章详细介绍了这一点。

s2和s3之间没有区别。 编译器将为您处理s1,并在编译期间将其连接起来。

我会说这应该决定编译器。 因为所有的字符串构建都可以优化,因为值已经知道。
我猜StringBuilder预先分配空间来追加更多的字符串。 如您所知+是二元运算符,因此无法一次构建两个以上字符串的串联。 因此,如果你想做s4 = s1 + s2 + s3 ,它将需要构建中间字符串(s1+s2)并且仅在s4