连接字符串最有效的方法是什么?

时间:2022-09-23 17:13:29

What's the most efficient way to concatenate strings?

连接字符串最有效的方法是什么?

17 个解决方案

#1


127  

The StringBuilder.Append() method is much better than using the + operator. But I've found that, when executing 1000 concatenations or less, String.Join() is even more efficient than StringBuilder.

StringBuilder.Append()方法比使用+运算符要好得多。但是我发现,当执行1000次或更少的连接时,String.Join()甚至比StringBuilder更高效。

StringBuilder sb = new StringBuilder();
sb.Append(someString);

The only problem with String.Join is that you have to concatenate the strings with a common delimiter. (Edit:) as @ryanversaw pointed out, you can make the delimiter string.Empty.

弦唯一的问题。连接是你必须用一个通用的分隔符连接字符串。(编辑:)正如@ryanversaw指出的,可以将分隔符string.Empty。

string key = String.Join("_", new String[] 
{ "Customers_Contacts", customerID, database, SessionID });

#2


237  

Rico Mariani, the .NET Performance guru, had an article on this very subject. It's not as simple as one might suspect. The basic advice is this:

net性能大师Rico Mariani就这个主题写了一篇文章。这并不像人们想象的那么简单。基本的建议是:

If your pattern looks like:

如果你的模式是:

x = f1(...) + f2(...) + f3(...) + f4(...)

x = f1(……)+ f2(……)+ f3(……)+ f4(……)

that's one concat and it's zippy, StringBuilder probably won't help.

那是一只猫,它很活泼,StringBuilder可能不会有帮助。

If your pattern looks like:

如果你的模式是:

if (...) x += f1(...)
if (...) x += f2(...)
if (...) x += f3(...)
if (...) x += f4(...)

如果(…)x + = f1(…)如果(…)x + = f2(…)如果(…)x + = f3(…)如果(…)x + = f4(…)

then you probably want StringBuilder.

然后你可能需要StringBuilder。

Yet another article to support this claim comes from Eric Lippert where he describes the optimizations performed on one line + concatenations in a detailed manner.

另一篇支持这一观点的文章来自Eric Lippert,他详细描述了在一行+连接上执行的优化。

#3


62  

There are 6 types of string concatenations:

有6种类型的字符串连接:

  1. Using the plus (+) symbol.
  2. 使用+(+)符号。
  3. Using string.Concat().
  4. 使用string.Concat()。
  5. Using string.Join().
  6. 使用string.Join()。
  7. Using string.Format().
  8. 使用string.Format()。
  9. Using string.Append().
  10. 使用string.Append()。
  11. Using StringBuilder.
  12. 使用StringBuilder。

In an experiment, it has been proved that string.Concat() is the best way to approach if the words are less than 1000(approximately) and if the words are more than 1000 then StringBuilder should be used.

在一个实验中,已经证明如果单词小于1000(大约),如果单词大于1000,那么使用string.Concat()是最好的方法。

For more information, check this site.

要了解更多信息,请访问这个网站。

string.Join() vs string.Concat()

The string.Concat method here is equivalent to the string.Join method invocation with an empty separator. Appending an empty string is fast, but not doing so is even faster, so the string.Concat method would be superior here.

的字符串。这里的Concat方法等价于字符串。使用空分隔符连接方法调用。附加一个空字符串是很快的,但是不这样做会更快,所以字符串。Concat方法在这里更优越。

#4


51  

From Chinh Do - StringBuilder is not always faster:

从Chinh Do - StringBuilder并不总是更快:

Rules of Thumb

的经验法则

  • When concatenating three dynamic string values or less, use traditional string concatenation.

    当连接三个动态字符串值或更少时,使用传统的字符串连接。

  • When concatenating more than three dynamic string values, use StringBuilder.

    当连接三个以上的动态字符串值时,使用StringBuilder。

  • When building a big string from several string literals, use either the @ string literal or the inline + operator.

    当从几个字符串文字构建一个大字符串时,可以使用@ string文字或inline +操作符。

Most of the time StringBuilder is your best bet, but there are cases as shown in that post that you should at least think about each situation.

大多数时候StringBuilder是您最好的选择,但是有一些例子显示您至少应该考虑每种情况。

#5


11  

If you're operating in a loop, StringBuilder is probably the way to go; it saves you the overhead of creating new strings regularly. In code that'll only run once, though, String.Concat is probably fine.

如果你在一个循环中运行,StringBuilder很可能是一个方法;它节省了您定期创建新字符串的开销。在代码中只运行一次,不过,字符串。Concat的可能就行。

However, Rico Mariani (.NET optimization guru) made up a quiz in which he stated at the end that, in most cases, he recommends String.Format.

然而,Rico马里安尼(。NET优化大师(NET optimization guru)制作了一个小测试,他在测试的最后说,在大多数情况下,他建议使用String.Format。

#6


6  

From this MSDN article:

从这个MSDN文章:

There is some overhead associated with creating a StringBuilder object, both in time and memory. On a machine with fast memory, a StringBuilder becomes worthwhile if you're doing about five operations. As a rule of thumb, I would say 10 or more string operations is a justification for the overhead on any machine, even a slower one.

与创建StringBuilder对象相关的开销包括时间和内存。在具有快速内存的机器上,如果您要执行大约5个操作,StringBuilder将是值得的。根据经验,我认为10个或更多的字符串操作是任何机器上开销的理由,即使是较慢的机器。

So if you trust MSDN go with StringBuilder if you have to do more than 10 strings operations/concatenations - otherwise simple string concat with '+' is fine.

因此,如果您信任MSDN与StringBuilder,如果您必须执行超过10个字符串操作/连接——否则简单的字符串concat与'+'是可以的。

#7


5  

Adding to the other answers, please keep in mind that StringBuilder can be told an initial amount of memory to allocate.

添加到其他答案中,请记住StringBuilder可以被告知要分配的初始内存数量。

The capacity parameter defines the maximum number of characters that can be stored in the memory allocated by the current instance. Its value is assigned to the Capacity property. If the number of characters to be stored in the current instance exceeds this capacity value, the StringBuilder object allocates additional memory to store them.

容量参数定义可以存储在当前实例分配的内存中的最大字符数。它的值被分配给容量属性。如果要存储在当前实例中的字符数超过此容量值,StringBuilder对象将分配额外的内存来存储它们。

If capacity is zero, the implementation-specific default capacity is used.

如果容量为零,则使用特定于实现的默认容量。

Repeatedly appending to a StringBuilder that hasn't been pre-allocated can result in a lot of unnecessary allocations just like repeatedly concatenating regular strings.

重复地向未预先分配的StringBuilder追加附加会导致大量不必要的分配,就像重复地连接常规字符串一样。

If you know how long the final string will be, can trivially calculate it, or can make an educated guess about the common case (allocating too much isn't necessarily a bad thing), you should be providing this information to the constructor or the Capacity property. Especially when running performance tests to compare StringBuilder with other methods like String.Concat, which do the same thing internally. Any test you see online which doesn't include StringBuilder pre-allocation in its comparisons is wrong.

如果您知道最终字符串的长度,可以简单地计算它,或者可以对常见情况进行有根据的猜测(分配太多不一定是坏事),那么您应该向构造函数或容量属性提供这些信息。特别是在运行性能测试以比较StringBuilder和其他方法(如String)时。Concat,在内部做同样的事情。你在网上看到的任何不包含StringBuilder预分配的测试都是错误的。

If you can't make any kind of guess about the size, you're probably writing a utility function which should have its own optional argument for controlling pre-allocation.

如果您无法对大小进行任何猜测,那么您可能正在编写一个实用函数,该函数应该有自己的可选参数来控制预分配。

#8


5  

Here is the fastest method I've evolved over a decade for my large-scale NLP app. I have variations for IEnumerable<T> and other input types, with and without separators of different types (Char, String), but here I show the simple case of concatenating all strings in an array into a single string, with no separator. Latest version here is developed and unit-tested on C# 7 and .NET 4.7.

这是最快的方法我已经进化了一个十年大规模的NLP应用。我变化IEnumerable < T >和其他输入类型,有或没有分隔符的不同类型(字符、字符串),但是在这里我展示简单的数组中所有字符串连接在一个字符串,没有分隔符。这里最新的版本是在c# 7和。net 4.7上开发和单元测试的。

There are two keys to higher performance; the first is to pre-compute the exact total size required. This step is trivial when the input is an array as shown here. For handling IEnumerable<T> instead, it is worth first gathering the strings into a temporary array for computing that total (The array is required to avoid calling ToString() more than once per element since technically, given the possibility of side-effects, doing so could change the expected semantics of a 'string join' operation).

有两个提高性能的关键;首先是预先计算所需的总大小。当输入是一个数组时,这个步骤很简单,如图所示。处理IEnumerable < T >相反,值得首先收集到一个临时的字符串数组的计算总(避免调用ToString()所需的数组每个元素不止一次从技术上,由于副作用的可能性,这样做可以改变的预期语义的字符串连接操作)。

Next, given the total allocation size of the final string, the biggest boost in performance is gained by building the result string in-place. Doing this requires the (perhaps controversial) technique of temporarily suspending the immutability of a new String which is initially allocated full of zeros. Any such controversy aside, however...

接下来,考虑到最终字符串的总分配大小,通过构建适当的结果字符串可以获得最大的性能提升。这样做需要(可能有争议的)暂停新字符串的不变性技术,该字符串最初被分配为满0。然而,撇开这些争议不谈……

...note that this is the only bulk-concatenation solution on this page which entirely avoids an extra round of allocation and copying by the String constructor.

…注意,这是页面上惟一的大容量连接解决方案,完全避免了字符串构造函数额外的分配和复制。

Complete code:

完整的代码:

/// <summary>
/// Concatenate the strings in 'rg', none of which may be null, into a single String.
/// </summary>
public static unsafe String StringJoin(this String[] rg)
{
    int i;
    if (rg == null || (i = rg.Length) == 0)
        return String.Empty;

    if (i == 1)
        return rg[0];

    String s, t;
    int cch = 0;
    do
        cch += rg[--i].Length;
    while (i > 0);
    if (cch == 0)
        return String.Empty;

    i = rg.Length;
    fixed (Char* _p = (s = new String(default(Char), cch)))
    {
        Char* pDst = _p + cch;
        do
            if ((t = rg[--i]).Length > 0)
                fixed (Char* pSrc = t)
                    memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length << 1));
        while (pDst > _p);
    }
    return s;
}

[DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);

I should mention that this code has a slight modification from what I use myself. In the original, I call the cpblk IL instruction from C# to do the actual copying. For simplicity and portability in the code here, I replaced that with P/Invoke memcpy instead, as you can see. For highest performance on x64 (but maybe not x86) you may want to use the cpblk method instead.

我应该指出,这段代码与我自己使用的代码有一点不同。在原始版本中,我调用c#中的cpblk IL指令进行实际的复制。为了简单和代码的可移植性,我将其替换为P/ memcpy,如您所见。对于x64(但可能不是x86)的最高性能,您可能需要使用cpblk方法。

#9


4  

It's also important to point it out that you should use the + operator if you are concatenating string literals.

同样重要的是要指出,如果要连接字符串文字,您应该使用+运算符。

When you concatenate string literals or string constants by using the + operator, the compiler creates a single string. No run time concatenation occurs.

当您使用+运算符连接字符串常量或字符串常量时,编译器将创建一个字符串。没有运行时连接发生。

How to: Concatenate Multiple Strings (C# Programming Guide)

如何:连接多个字符串(c#编程指南)

#10


2  

The most efficient is to use StringBuilder, like so:

最有效的方法是使用StringBuilder,如下所示:

StringBuilder sb = new StringBuilder();
sb.Append("string1");
sb.Append("string2");
...etc...
String strResult = sb.ToString();

@jonezy: String.Concat is fine if you have a couple of small things. But if you're concatenating megabytes of data, your program will likely tank.

@jonezy:字符串。如果你有一些小事情,Concat是可以的。但是,如果您正在连接兆字节的数据,您的程序可能会崩溃。

#11


2  

Following may be one more alternate solution to concatenate multiple strings.

下面可能是连接多个字符串的另一种解决方案。

String str1 = "sometext";
string str2 = "some other text";

string afterConcate = $"{str1}{str2}";

string interpolation

字符串插值

#12


1  

It really depends on your usage pattern. A detailed benchmark between string.Join, string,Concat and string.Format can be found here: String.Format Isn't Suitable for Intensive Logging

这取决于你的使用模式。字符串之间的详细基准。加入,字符串,Concat和字符串。格式可以在这里找到:String。格式不适合密集的日志记录

(This is actually the same answer I gave to this question)

(这和我给这个问题的答案是一样的)

#13


1  

System.String is immutable. When we modify the value of a string variable then a new memory is allocated to the new value and the previous memory allocation released. System.StringBuilder was designed to have concept of a mutable string where a variety of operations can be performed without allocation separate memory location for the modified string.

系统。字符串是不可变的。当我们修改字符串变量的值时,一个新的内存将被分配给新的值,并释放以前的内存分配。系统。StringBuilder被设计成具有可变字符串的概念,在这里可以执行各种操作,而无需为修改后的字符串分配单独的内存位置。

#14


1  

Try this 2 pieces of code and you will find the solution.

试试这两段代码,你就会找到解决方案。

 static void Main(string[] args)
    {
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < 10000000; i++)
        {
            s.Append( i.ToString());
        }
        Console.Write("End");
        Console.Read();
    }

Vs

Vs

static void Main(string[] args)
    {
        string s = "";
        for (int i = 0; i < 10000000; i++)
        {
            s += i.ToString();
        }
        Console.Write("End");
        Console.Read();
    }

You will find that 1st code will end really quick and the memory will be in a good amount.

你会发现第一段代码很快就会结束,内存也会很大。

The second code maybe the memory will be ok, but it will take longer... much longer. So if you have an application for a lot of users and you need speed, use the 1st. If you have an app for a short term one user app, maybe you can use both or the 2nd will be more "natural" for developers.

第二段代码可能内存没问题,但是需要更长的时间……更长的时间。如果你有一个适用于很多用户的应用程序,你需要速度,请使用第一个。如果你有一个短期用户应用,也许你可以同时使用两个,或者第二个对开发者来说更“自然”。

Cheers.

欢呼。

#15


0  

For just two strings, you definitely do not want to use StringBuilder. There is some threshold above which the StringBuilder overhead is less than the overhead of allocating multiple strings.

对于两个字符串,您肯定不希望使用StringBuilder。在上面有一个阈值,StringBuilder的开销小于分配多个字符串的开销。

So, for more that 2-3 strings, use DannySmurf's code. Otherwise, just use the + operator.

因此,对于2-3个字符串,使用DannySmurf的代码。否则,只需使用+运算符。

#16


0  

It would depend on the code. StringBuilder is more efficient generally, but if you're only concatenating a few strings and doing it all in one line, code optimizations will likely take care of it for you. It's important to think about how the code looks too: for larger sets StringBuilder will make it easier to read, for small ones StringBuilder will just add needless clutter.

这取决于代码。StringBuilder通常更高效,但是如果只连接一些字符串并在一行中执行,代码优化很可能会为您处理。考虑代码的外观也很重要:对于较大的集合,StringBuilder将使其更易于阅读,对于较小的集合,StringBuilder将只添加不必要的混乱。

#17


0  

Another solution:

另一个解决方案:

inside the loop, use List instead of string.

在循环内部,使用List而不是string。

List<string> lst= new List<string>();

for(int i=0; i<100000; i++){
    ...........
    lst.Add(...);
}
return String.Join("", lst.ToArray());;

it is very very fast.

它非常快。

#1


127  

The StringBuilder.Append() method is much better than using the + operator. But I've found that, when executing 1000 concatenations or less, String.Join() is even more efficient than StringBuilder.

StringBuilder.Append()方法比使用+运算符要好得多。但是我发现,当执行1000次或更少的连接时,String.Join()甚至比StringBuilder更高效。

StringBuilder sb = new StringBuilder();
sb.Append(someString);

The only problem with String.Join is that you have to concatenate the strings with a common delimiter. (Edit:) as @ryanversaw pointed out, you can make the delimiter string.Empty.

弦唯一的问题。连接是你必须用一个通用的分隔符连接字符串。(编辑:)正如@ryanversaw指出的,可以将分隔符string.Empty。

string key = String.Join("_", new String[] 
{ "Customers_Contacts", customerID, database, SessionID });

#2


237  

Rico Mariani, the .NET Performance guru, had an article on this very subject. It's not as simple as one might suspect. The basic advice is this:

net性能大师Rico Mariani就这个主题写了一篇文章。这并不像人们想象的那么简单。基本的建议是:

If your pattern looks like:

如果你的模式是:

x = f1(...) + f2(...) + f3(...) + f4(...)

x = f1(……)+ f2(……)+ f3(……)+ f4(……)

that's one concat and it's zippy, StringBuilder probably won't help.

那是一只猫,它很活泼,StringBuilder可能不会有帮助。

If your pattern looks like:

如果你的模式是:

if (...) x += f1(...)
if (...) x += f2(...)
if (...) x += f3(...)
if (...) x += f4(...)

如果(…)x + = f1(…)如果(…)x + = f2(…)如果(…)x + = f3(…)如果(…)x + = f4(…)

then you probably want StringBuilder.

然后你可能需要StringBuilder。

Yet another article to support this claim comes from Eric Lippert where he describes the optimizations performed on one line + concatenations in a detailed manner.

另一篇支持这一观点的文章来自Eric Lippert,他详细描述了在一行+连接上执行的优化。

#3


62  

There are 6 types of string concatenations:

有6种类型的字符串连接:

  1. Using the plus (+) symbol.
  2. 使用+(+)符号。
  3. Using string.Concat().
  4. 使用string.Concat()。
  5. Using string.Join().
  6. 使用string.Join()。
  7. Using string.Format().
  8. 使用string.Format()。
  9. Using string.Append().
  10. 使用string.Append()。
  11. Using StringBuilder.
  12. 使用StringBuilder。

In an experiment, it has been proved that string.Concat() is the best way to approach if the words are less than 1000(approximately) and if the words are more than 1000 then StringBuilder should be used.

在一个实验中,已经证明如果单词小于1000(大约),如果单词大于1000,那么使用string.Concat()是最好的方法。

For more information, check this site.

要了解更多信息,请访问这个网站。

string.Join() vs string.Concat()

The string.Concat method here is equivalent to the string.Join method invocation with an empty separator. Appending an empty string is fast, but not doing so is even faster, so the string.Concat method would be superior here.

的字符串。这里的Concat方法等价于字符串。使用空分隔符连接方法调用。附加一个空字符串是很快的,但是不这样做会更快,所以字符串。Concat方法在这里更优越。

#4


51  

From Chinh Do - StringBuilder is not always faster:

从Chinh Do - StringBuilder并不总是更快:

Rules of Thumb

的经验法则

  • When concatenating three dynamic string values or less, use traditional string concatenation.

    当连接三个动态字符串值或更少时,使用传统的字符串连接。

  • When concatenating more than three dynamic string values, use StringBuilder.

    当连接三个以上的动态字符串值时,使用StringBuilder。

  • When building a big string from several string literals, use either the @ string literal or the inline + operator.

    当从几个字符串文字构建一个大字符串时,可以使用@ string文字或inline +操作符。

Most of the time StringBuilder is your best bet, but there are cases as shown in that post that you should at least think about each situation.

大多数时候StringBuilder是您最好的选择,但是有一些例子显示您至少应该考虑每种情况。

#5


11  

If you're operating in a loop, StringBuilder is probably the way to go; it saves you the overhead of creating new strings regularly. In code that'll only run once, though, String.Concat is probably fine.

如果你在一个循环中运行,StringBuilder很可能是一个方法;它节省了您定期创建新字符串的开销。在代码中只运行一次,不过,字符串。Concat的可能就行。

However, Rico Mariani (.NET optimization guru) made up a quiz in which he stated at the end that, in most cases, he recommends String.Format.

然而,Rico马里安尼(。NET优化大师(NET optimization guru)制作了一个小测试,他在测试的最后说,在大多数情况下,他建议使用String.Format。

#6


6  

From this MSDN article:

从这个MSDN文章:

There is some overhead associated with creating a StringBuilder object, both in time and memory. On a machine with fast memory, a StringBuilder becomes worthwhile if you're doing about five operations. As a rule of thumb, I would say 10 or more string operations is a justification for the overhead on any machine, even a slower one.

与创建StringBuilder对象相关的开销包括时间和内存。在具有快速内存的机器上,如果您要执行大约5个操作,StringBuilder将是值得的。根据经验,我认为10个或更多的字符串操作是任何机器上开销的理由,即使是较慢的机器。

So if you trust MSDN go with StringBuilder if you have to do more than 10 strings operations/concatenations - otherwise simple string concat with '+' is fine.

因此,如果您信任MSDN与StringBuilder,如果您必须执行超过10个字符串操作/连接——否则简单的字符串concat与'+'是可以的。

#7


5  

Adding to the other answers, please keep in mind that StringBuilder can be told an initial amount of memory to allocate.

添加到其他答案中,请记住StringBuilder可以被告知要分配的初始内存数量。

The capacity parameter defines the maximum number of characters that can be stored in the memory allocated by the current instance. Its value is assigned to the Capacity property. If the number of characters to be stored in the current instance exceeds this capacity value, the StringBuilder object allocates additional memory to store them.

容量参数定义可以存储在当前实例分配的内存中的最大字符数。它的值被分配给容量属性。如果要存储在当前实例中的字符数超过此容量值,StringBuilder对象将分配额外的内存来存储它们。

If capacity is zero, the implementation-specific default capacity is used.

如果容量为零,则使用特定于实现的默认容量。

Repeatedly appending to a StringBuilder that hasn't been pre-allocated can result in a lot of unnecessary allocations just like repeatedly concatenating regular strings.

重复地向未预先分配的StringBuilder追加附加会导致大量不必要的分配,就像重复地连接常规字符串一样。

If you know how long the final string will be, can trivially calculate it, or can make an educated guess about the common case (allocating too much isn't necessarily a bad thing), you should be providing this information to the constructor or the Capacity property. Especially when running performance tests to compare StringBuilder with other methods like String.Concat, which do the same thing internally. Any test you see online which doesn't include StringBuilder pre-allocation in its comparisons is wrong.

如果您知道最终字符串的长度,可以简单地计算它,或者可以对常见情况进行有根据的猜测(分配太多不一定是坏事),那么您应该向构造函数或容量属性提供这些信息。特别是在运行性能测试以比较StringBuilder和其他方法(如String)时。Concat,在内部做同样的事情。你在网上看到的任何不包含StringBuilder预分配的测试都是错误的。

If you can't make any kind of guess about the size, you're probably writing a utility function which should have its own optional argument for controlling pre-allocation.

如果您无法对大小进行任何猜测,那么您可能正在编写一个实用函数,该函数应该有自己的可选参数来控制预分配。

#8


5  

Here is the fastest method I've evolved over a decade for my large-scale NLP app. I have variations for IEnumerable<T> and other input types, with and without separators of different types (Char, String), but here I show the simple case of concatenating all strings in an array into a single string, with no separator. Latest version here is developed and unit-tested on C# 7 and .NET 4.7.

这是最快的方法我已经进化了一个十年大规模的NLP应用。我变化IEnumerable < T >和其他输入类型,有或没有分隔符的不同类型(字符、字符串),但是在这里我展示简单的数组中所有字符串连接在一个字符串,没有分隔符。这里最新的版本是在c# 7和。net 4.7上开发和单元测试的。

There are two keys to higher performance; the first is to pre-compute the exact total size required. This step is trivial when the input is an array as shown here. For handling IEnumerable<T> instead, it is worth first gathering the strings into a temporary array for computing that total (The array is required to avoid calling ToString() more than once per element since technically, given the possibility of side-effects, doing so could change the expected semantics of a 'string join' operation).

有两个提高性能的关键;首先是预先计算所需的总大小。当输入是一个数组时,这个步骤很简单,如图所示。处理IEnumerable < T >相反,值得首先收集到一个临时的字符串数组的计算总(避免调用ToString()所需的数组每个元素不止一次从技术上,由于副作用的可能性,这样做可以改变的预期语义的字符串连接操作)。

Next, given the total allocation size of the final string, the biggest boost in performance is gained by building the result string in-place. Doing this requires the (perhaps controversial) technique of temporarily suspending the immutability of a new String which is initially allocated full of zeros. Any such controversy aside, however...

接下来,考虑到最终字符串的总分配大小,通过构建适当的结果字符串可以获得最大的性能提升。这样做需要(可能有争议的)暂停新字符串的不变性技术,该字符串最初被分配为满0。然而,撇开这些争议不谈……

...note that this is the only bulk-concatenation solution on this page which entirely avoids an extra round of allocation and copying by the String constructor.

…注意,这是页面上惟一的大容量连接解决方案,完全避免了字符串构造函数额外的分配和复制。

Complete code:

完整的代码:

/// <summary>
/// Concatenate the strings in 'rg', none of which may be null, into a single String.
/// </summary>
public static unsafe String StringJoin(this String[] rg)
{
    int i;
    if (rg == null || (i = rg.Length) == 0)
        return String.Empty;

    if (i == 1)
        return rg[0];

    String s, t;
    int cch = 0;
    do
        cch += rg[--i].Length;
    while (i > 0);
    if (cch == 0)
        return String.Empty;

    i = rg.Length;
    fixed (Char* _p = (s = new String(default(Char), cch)))
    {
        Char* pDst = _p + cch;
        do
            if ((t = rg[--i]).Length > 0)
                fixed (Char* pSrc = t)
                    memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length << 1));
        while (pDst > _p);
    }
    return s;
}

[DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);

I should mention that this code has a slight modification from what I use myself. In the original, I call the cpblk IL instruction from C# to do the actual copying. For simplicity and portability in the code here, I replaced that with P/Invoke memcpy instead, as you can see. For highest performance on x64 (but maybe not x86) you may want to use the cpblk method instead.

我应该指出,这段代码与我自己使用的代码有一点不同。在原始版本中,我调用c#中的cpblk IL指令进行实际的复制。为了简单和代码的可移植性,我将其替换为P/ memcpy,如您所见。对于x64(但可能不是x86)的最高性能,您可能需要使用cpblk方法。

#9


4  

It's also important to point it out that you should use the + operator if you are concatenating string literals.

同样重要的是要指出,如果要连接字符串文字,您应该使用+运算符。

When you concatenate string literals or string constants by using the + operator, the compiler creates a single string. No run time concatenation occurs.

当您使用+运算符连接字符串常量或字符串常量时,编译器将创建一个字符串。没有运行时连接发生。

How to: Concatenate Multiple Strings (C# Programming Guide)

如何:连接多个字符串(c#编程指南)

#10


2  

The most efficient is to use StringBuilder, like so:

最有效的方法是使用StringBuilder,如下所示:

StringBuilder sb = new StringBuilder();
sb.Append("string1");
sb.Append("string2");
...etc...
String strResult = sb.ToString();

@jonezy: String.Concat is fine if you have a couple of small things. But if you're concatenating megabytes of data, your program will likely tank.

@jonezy:字符串。如果你有一些小事情,Concat是可以的。但是,如果您正在连接兆字节的数据,您的程序可能会崩溃。

#11


2  

Following may be one more alternate solution to concatenate multiple strings.

下面可能是连接多个字符串的另一种解决方案。

String str1 = "sometext";
string str2 = "some other text";

string afterConcate = $"{str1}{str2}";

string interpolation

字符串插值

#12


1  

It really depends on your usage pattern. A detailed benchmark between string.Join, string,Concat and string.Format can be found here: String.Format Isn't Suitable for Intensive Logging

这取决于你的使用模式。字符串之间的详细基准。加入,字符串,Concat和字符串。格式可以在这里找到:String。格式不适合密集的日志记录

(This is actually the same answer I gave to this question)

(这和我给这个问题的答案是一样的)

#13


1  

System.String is immutable. When we modify the value of a string variable then a new memory is allocated to the new value and the previous memory allocation released. System.StringBuilder was designed to have concept of a mutable string where a variety of operations can be performed without allocation separate memory location for the modified string.

系统。字符串是不可变的。当我们修改字符串变量的值时,一个新的内存将被分配给新的值,并释放以前的内存分配。系统。StringBuilder被设计成具有可变字符串的概念,在这里可以执行各种操作,而无需为修改后的字符串分配单独的内存位置。

#14


1  

Try this 2 pieces of code and you will find the solution.

试试这两段代码,你就会找到解决方案。

 static void Main(string[] args)
    {
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < 10000000; i++)
        {
            s.Append( i.ToString());
        }
        Console.Write("End");
        Console.Read();
    }

Vs

Vs

static void Main(string[] args)
    {
        string s = "";
        for (int i = 0; i < 10000000; i++)
        {
            s += i.ToString();
        }
        Console.Write("End");
        Console.Read();
    }

You will find that 1st code will end really quick and the memory will be in a good amount.

你会发现第一段代码很快就会结束,内存也会很大。

The second code maybe the memory will be ok, but it will take longer... much longer. So if you have an application for a lot of users and you need speed, use the 1st. If you have an app for a short term one user app, maybe you can use both or the 2nd will be more "natural" for developers.

第二段代码可能内存没问题,但是需要更长的时间……更长的时间。如果你有一个适用于很多用户的应用程序,你需要速度,请使用第一个。如果你有一个短期用户应用,也许你可以同时使用两个,或者第二个对开发者来说更“自然”。

Cheers.

欢呼。

#15


0  

For just two strings, you definitely do not want to use StringBuilder. There is some threshold above which the StringBuilder overhead is less than the overhead of allocating multiple strings.

对于两个字符串,您肯定不希望使用StringBuilder。在上面有一个阈值,StringBuilder的开销小于分配多个字符串的开销。

So, for more that 2-3 strings, use DannySmurf's code. Otherwise, just use the + operator.

因此,对于2-3个字符串,使用DannySmurf的代码。否则,只需使用+运算符。

#16


0  

It would depend on the code. StringBuilder is more efficient generally, but if you're only concatenating a few strings and doing it all in one line, code optimizations will likely take care of it for you. It's important to think about how the code looks too: for larger sets StringBuilder will make it easier to read, for small ones StringBuilder will just add needless clutter.

这取决于代码。StringBuilder通常更高效,但是如果只连接一些字符串并在一行中执行,代码优化很可能会为您处理。考虑代码的外观也很重要:对于较大的集合,StringBuilder将使其更易于阅读,对于较小的集合,StringBuilder将只添加不必要的混乱。

#17


0  

Another solution:

另一个解决方案:

inside the loop, use List instead of string.

在循环内部,使用List而不是string。

List<string> lst= new List<string>();

for(int i=0; i<100000; i++){
    ...........
    lst.Add(...);
}
return String.Join("", lst.ToArray());;

it is very very fast.

它非常快。