C# 字符串连接性能的差异

C# 字符串连接性能的差异,c#,.net,C#,.net,我知道在连接字符串时应该使用StringBuilder,但我只是想知道连接字符串变量和字符串文本是否有区别。那么,建筑s1、s2和s3的性能是否存在差异 string foo = "foo"; string bar = "bar"; string s1 = "foo" + "bar"; string s2 = foo + "bar"; string s3 = foo + bar; s2和s3之间没有区别。编译器将为您处理s1,并在编译时将其连接起来。s2和s3之间没有区别。编译器将为您处理s

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

string foo = "foo";
string bar = "bar";

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

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

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

编译器可以在编译时连接文字,因此“foo”+“bar”将直接编译为“foobar”,而无需在运行时执行任何操作


除此之外,我怀疑这两者之间有什么显著的区别。

编译器可以在编译时连接文本,因此“foo”+“bar”可以直接编译为“foobar”,而无需在运行时执行任何操作


除此之外,我怀疑是否有任何显著的区别。

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

这是串接字符串的一般规则。当您有一组要连接在一起的项目(可能是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是连接这些字符串的最有效的方法,因为您将始终必须重新分配缓冲区以考虑添加的新字符串项(您不知道还剩下多少个)。

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

这是串接字符串的一般规则。当您有一组要串接在一起的项目时(无论是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是连接这些字符串的最有效的方法,因为您将始终必须重新分配缓冲区以考虑添加的新字符串项(您不知道还剩下多少个)。

您的“知识”不正确。在连接字符串时,有时应该使用
StringBuilder
。尤其是,当无法在一次表达式中执行连接时,您应该这样做

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

string foo = "foo";
string bar = "bar";

string s1 = "foobar";
string s2 = String.Concat(foo, "bar");
string s3 = String.Concat(foo, bar);
使用
StringBuilder
会降低任何效率-特别是它会将
s1
的串联从编译时推到执行时。对于
s2
s3
,它会强制创建额外的对象(
StringBuilder
)以及可能分配一个不必要的大字符串

我有一个更详细的说明。

您的“知识”是不正确的。在连接字符串时,您有时应该使用
StringBuilder
。特别是,当您不能在一个表达式中执行连接时,您应该这样做

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

string foo = "foo";
string bar = "bar";

string s1 = "foobar";
string s2 = String.Concat(foo, "bar");
string s3 = String.Concat(foo, bar);
使用
StringBuilder
会降低任何效率-特别是它会将
s1
的串联从编译时推到执行时。对于
s2
s3
,它会强制创建额外的对象(
StringBuilder
)以及可能分配一个不必要的大字符串


我有一个更详细的说明。

我想说这应该决定编译器。因为所有的字符串构建都可以优化,因为值是已知的。

我猜StringBuilder会预先分配空间来追加更多字符串。正如您所知,
+
是二进制运算符,因此无法一次构建两个以上字符串的串联。因此,如果要执行
s4=s1+s2+s3
操作,则需要构建中间字符串
(s1+s2)
而且只有在这之后,
s4

我会说这应该决定编译器。因为所有的字符串构建都可以优化,因为值是已知的。
我猜StringBuilder会预先分配空间来追加更多字符串。正如您所知,
+
是二进制运算符,因此无法一次构建两个以上字符串的串联。因此,如果要执行
s4=s1+s2+s3
,则需要构建