C# 字符串连接与字符串生成器。表现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1612797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:23:17  来源:igfitidea点击:

String concatenation vs String Builder. Performance

c#performancestring

提问by Jorge Córdoba

I have a situation where I need to concatenate several string to form an id of a class. Basically I'm just looping in a list to get the ToString values of the objects and then concatenating them.

我有一种情况,我需要连接几个字符串以形成一个类的 id。基本上,我只是在列表中循环以获取对象的 ToString 值,然后将它们连接起来。

foreach (MyObject o in myList)
  result += o.ToString();

The list is NOT expected to have more than 5 elements (although it could but that's a very, very marginal case) and usually will have from 1 to 3 elements, being common for it to just have one or two.

该列表预计不会有超过 5 个元素(尽管它可以,但这是一个非常非常边缘的情况)并且通常会有 1 到 3 个元素,通常只有一两个。

What would be more performance, keeping the concatenation or using an StringBuilder?

保持串联或使用 StringBuilder 会有什么更高的性能?

StringBuilder bld = new StringBuilder()
foreach (MyObject o in myList)
  bld.Append(o.ToString());

I'm unsure if creating the StringBuilder will take more time than standard concatenation for the most usual case.

我不确定在最常见的情况下,创建 StringBuilder 是否比标准连接花费更多的时间。

This is lazy, items on the list do not change once created so the id is lazily constructed once when called.

这是惰性的,列表中的项目一旦创建就不会更改,因此在调用时会惰性地构造一次 id。

As a side note... Should I use a fixed array instead of a List? Would I get any performance or memory improvement if I do? (List is only used as an IEnumerable anyway)

作为旁注......我应该使用固定数组而不是列表吗?如果我这样做,我会获得任何性能或内存改进吗?(无论如何,List 仅用作 IEnumerable)

A more general view of the question could be, how many strings are enough to stop concatenating and start building?

这个问题的一个更一般的观点可能是,有多少字符串足以停止连接并开始构建?

Should I even bother to test case the scenario?

我什至应该费心测试场景吗?

if (myList.Count > 4) 
  ConcatWithStringBuilder(myList);

采纳答案by Daniel Robinson

The usual answer is that string concatenation is more efficient for between 4 to 8 strings. It depends on whose blog you read.

通常的答案是字符串连接对于 4 到 8 个字符串更有效。这取决于您阅读谁的博客。

Don't write a test to decide on which method to use. If you are unsure of whether it will go over the magic limit, then just use StringBuilder.

不要编写测试来决定使用哪种方法。如果您不确定它是否会超过魔法限制,那么只需使用 StringBuilder。

Run this code to see the results for yourself:

运行此代码以查看结果:

const int sLen=30, Loops=5000;
DateTime sTime, eTime;
int i;
string sSource = new String('X', sLen);
string sDest = "";
// 
// Time string concatenation.
// 
sTime = DateTime.Now;
for(i=0;i<Loops;i++) sDest += sSource;
eTime = DateTime.Now;
Console.WriteLine("Concatenation took " + (eTime - sTime).TotalSeconds + " seconds.");
// 
// Time StringBuilder.
// 
sTime = DateTime.Now;
System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
for(i=0;i<Loops;i++) sb.Append(sSource);
sDest = sb.ToString();
eTime = DateTime.Now;
Console.WriteLine("String Builder took " + (eTime - sTime).TotalSeconds + " seconds.");
// 
// Make the console window stay open
// so that you can see the results when running from the IDE.
// 
Console.WriteLine();
Console.Write("Press Enter to finish ... ");
Console.Read();

Ref. http://support.microsoft.com/kb/306822

参考 http://support.microsoft.com/kb/306822

回答by kemiller2002

The string builder will most likely be marginally faster in this case, but really it's probably not going to be enough to fret about. It really is going to depend on two things, the number of times you are re-creating the string (because strings are immutable and joining forces a new string to be created from the two existing ones), and the size of the string elements you are concatenating together. Concatenating five strings which are 2 bytes each is going to be very different than concatenating 5 strings together which are 5000 bytes each, because the the longer the string, the more work the system has to do to allocate memory and garbage collect objects that are no longer in use. The string builder is an all around better bet, because it has already been optimized to join strings together, and you don't really have to worry about performance considerations.

在这种情况下,字符串生成器很可能会稍微快一点,但实际上它可能还不够担心。它真的将取决于两件事,您重新创建字符串的次数(因为字符串是不可变的,并且连接会强制从两个现有字符串创建一个新字符串),以及您创建的字符串元素的大小串联在一起。将每个 2 个字节的 5 个字符串连接在一起与将每个 5000 个字节的 5 个字符串连接在一起非常不同,因为字符串越长,系统必须做的工作就越多,以分配内存和垃圾收集对象使用时间更长。字符串生成器是一个更好的选择,因为它已经被优化为将字符串连接在一起,而你没有

With all of this in mind, if you know about how large the end size of final the string is going to be, string builder will almost certainly be faster. When you tell it how much memory to allocate for the final string, it won't have to go through the process of reallocating memory.

考虑到所有这些,如果您知道最终字符串的最终大小有多大,那么字符串生成器几乎肯定会更快。当您告诉它为最终字符串分配多少内存时,它就不必经历重新分配内存的过程。

回答by Lucero

If you can estimate the number of bytes which will be used for the full string (and use this to initialize the StringBuilder's capacity), the StringBuilder is likely to outperform the String class when doing more than approximately 3 concats.

如果您可以估计将用于完整字符串的字节数(并使用它来初始化 StringBuilder 的容量),则 StringBuilder 在执行大约 3 个以上的连接时可能会优于 String 类。

回答by Lucero

I support the idea of keeping things simple until you have a good reason to make them complex.

我支持让事情保持简单的想法,直到你有充分的理由让事情变得复杂。

For something like 2-5 elements there is no point in using the StringBuilder (unless you repeat this concatenation continuously). The better readable syntax "+=" has more value.

对于像 2-5 个元素这样的东西,使用 StringBuilder 没有意义(除非你连续重复这个连接)。更好的可读语法“+=”具有更多价值。

回答by JeeBee

I'd use StringBuilder just because you want to be consistent throughout an application. Instantiating a Java/.NET object is not time consuming either, although I would guess that there would be some housekeeping upon setup for StringBuilder. Not much worse than creating multiple String objects via concatenation surely.

我会使用 StringBuilder 只是因为您希望在整个应用程序中保持一致。实例化 Java/.NET 对象也不耗时,尽管我猜想在为 StringBuilder 设置时会有一些内务处理。肯定不会比通过连接创建多个 String 对象差多少。

回答by Foxfire

A more general view of the question could be, how many strings are enough to stop concatenating and start building?

这个问题的一个更一般的观点可能是,有多少字符串足以停止连接并开始构建?

This depends on the length of the strings and if you can predict the target length then you should supply the length to the StringBuilderconstructorand if you concatenate them all at once or within several steps.

这取决于字符串的长度,如果您可以预测目标长度,那么您应该将长度提供给StringBuilder构造函数,如果您一次或在几个步骤内将它们全部连接起来。

If you concatenate them at once (like s = "A" + "b" + "c" + "d")then using StringBuilderlikely never makes sense.

如果您一次连接它们(如s = "A" + "b" + "c" + "d"),那么使用StringBuilder可能永远没有意义。

If you can exactly predict the length then even for 3 Strings StringBuilder would be faster.

如果您可以准确预测长度,那么即使是 3 个字符串 StringBuilder 也会更快。

Usually StringBuilder is faster if you have more than about 5 concats. But even then just concatenating the Strings usually has little overhead (unless it runs in a tight loop).

如果您有超过 5 个连接,通常 StringBuilder 会更快。但即使这样,连接字符串通常也没有什么开销(除非它在一个紧密的循环中运行)。

As soon as you reach 10 concats using StringBuilderwill likely be favorable.

一旦您达到 10 个 concats,使用StringBuilder可能是有利的。

Edit: Just to make it clear: In your case you should clearly go without StringBuilder.

编辑:只是为了清楚起见:在您的情况下,您应该清楚地不使用StringBuilder.

回答by Paul Sasik

IMO string concatenation is more readable. You use + and += instead of strBldInstance.Add() which can muddy the code a little more,

IMO 字符串连接更具可读性。您使用 + 和 += 而不是 strBldInstance.Add() ,这会使代码更加混乱,

StringBuilder exists to make concatenation more performant, much more, but i usually sacrifice a smidgen of performance for code readability. Your code's not going to affected if you cat a few strings here and there. And for that code block that does cat many strings often, use StringBuilder.

StringBuilder 的存在是为了使串联更高效,但我通常会为了代码可读性而牺牲一点性能。如果您在这里和那里输入一些字符串,您的代码不会受到影响。对于经常处理许多字符串的代码块,请使用 StringBuilder。

回答by Luke Duddridge

If you can, you could have some fun and do away with the for loop altogether and use aggregate?

如果可以,您可以玩得开心,完全取消 for 循环并使用聚合吗?

var concatstring = mylist.Aggregate("", (acc, item) => acc + "." + item);

not sure on the overhead of this though?

不确定这个开销?

回答by Display Name

Why can't you just use

为什么你不能使用

String.Concat(myList)

instead of reinventing the wheel? It has high performance and yet is dead simple.
More info here: http://msdn.microsoft.com/en-us/library/system.string.concat.aspx

而不是重新发明轮子?它具有高性能,但非常简单。
更多信息:http: //msdn.microsoft.com/en-us/library/system.string.concat.aspx

回答by Aimal Khan

Found this (performance) topic while solving a leetcode problem. For a string having > 42k (or more) chars, stringBuilder is faster for some reason.

在解决 leetcode 问题时发现了这个(性能)主题。对于具有 > 42k(或更多)字符的字符串,出于某种原因,stringBuilder 速度更快。

My following code for reversing a string worked in the specified case (> 42k chars) with StringBuilder.

我的以下用于反转字符串的代码使用 StringBuilder 在指定的情况下(> 42k 个字符)起作用。

public static string ReverseString(string s)
{
   var toReturn = new StringBuilder();
   for (var i = s.Length - 1; i >= 0; i--)
   {
      toReturn.Append(s[i]);
      }
   return toReturn.ToString();
}

but the same function didn't work with string concatenation i.e. toReturn += s[i].

但相同的函数不适用于字符串连接,即toReturn += s[i]