代码之家  ›  专栏  ›  技术社区  ›  Homer

字符串连接性能的差异

  •  0
  • Homer  · 技术社区  · 14 年前

    我知道你应该用 StringBuilder 当串接字符串时,我只是想知道串接字符串变量和字符串文本是否有区别。那么,s1、s2和s3号楼的性能有区别吗?

    string foo = "foo";
    string bar = "bar";
    
    string s1 = "foo" + "bar";
    string s2 = foo + "bar";
    string s3 = foo + bar;
    
    5 回复  |  直到 14 年前
        1
  •  3
  •   casperOne    14 年前

    在您提出的情况下,实际上最好对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是连接这些字符串的最有效的方法,因为您将始终需要重新计算缓冲区以考虑新的正在添加的字符串项(其中您不知道还剩多少个)。

        2
  •  2
  •   Mattias S    14 年前

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

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

        3
  •  1
  •   Jon Skeet    14 年前

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

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

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

    使用A 字符串拼接 会降低效率-特别是它会推动 s1 从编译时到执行时。为了 s2 s3 它将强制创建一个额外的对象( 字符串拼接 )以及可能分配一个 string 这是不必要的大。

    我有一个 article 更详细地说。

        4
  •  1
  •   kemiller2002    14 年前

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

        5
  •  -1
  •   ony    14 年前

    我认为这应该决定编译器。因为所有的字符串构建都可以优化,因为值是已知的。
    我猜stringbuilder会预先分配空间来附加更多的字符串。正如你所知道的 + 是二进制运算符,因此无法一次建立两个以上字符串的连接。所以如果你想的话 s4 = s1 + s2 + s3 需要建造中间管柱 (s1+s2) 只有在那之后 s4 .