Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字符串与StringBuilder_C#_.net_Performance - Fatal编程技术网

C# 字符串与StringBuilder

C# 字符串与StringBuilder,c#,.net,performance,C#,.net,Performance,我理解String和StringBuilder之间的区别(StringBuilder是可变的),但是这两者之间的性能差异很大吗 我正在处理的程序有很多大小写驱动的字符串附加(500+)。使用StringBuilder是更好的选择吗?从内存的角度来看,StringBuilder的性能会更好。至于处理,执行时间上的差异可能可以忽略不计。我认为如果需要将4个以上的字符串附加在一起,StringBuilder会更快。另外,它还可以做一些很酷的事情,比如追加字符串。在.NET中,StringBuilder

我理解
String
StringBuilder
之间的区别(
StringBuilder
是可变的),但是这两者之间的性能差异很大吗


我正在处理的程序有很多大小写驱动的字符串附加(500+)。使用
StringBuilder
是更好的选择吗?

从内存的角度来看,StringBuilder的性能会更好。至于处理,执行时间上的差异可能可以忽略不计。

我认为如果需要将4个以上的字符串附加在一起,StringBuilder会更快。另外,它还可以做一些很酷的事情,比如追加字符串。

在.NET中,StringBuilder仍然比追加字符串快。我很确定,在Java中,当你附加字符串时,他们只是在引擎盖下创建一个StringBuffer,所以这并没有什么区别。我不知道他们为什么还没有在.NET中这样做。

是的,性能差异很大。请参阅知识库文章“”

我一直试图先编写清晰的代码,然后再优化性能。这比反过来做容易多了!然而,在看到了这两个应用程序在性能上的巨大差异之后,我现在仔细考虑一下


幸运的是,对代码运行性能分析以查看您在哪里花费了时间,然后在需要时修改它以使用
StringBuilder

StringBuilder可能更可取。原因是它分配的空间超过了当前所需的空间(您可以设置字符数),以便为将来的追加留出空间。然后,那些适合当前缓冲区的未来附件不需要任何内存分配或垃圾收集,这可能会很昂贵。通常,我使用StringBuilder进行复杂的字符串合并或多种格式设置,然后在数据完成后转换为普通字符串,我希望再次使用不可变对象。

如果要进行大量字符串连接,请使用StringBuilder。当您连接一个字符串时,每次都会创建一个新字符串,占用更多内存


Alex

在前面的回答之后,我在思考类似问题时总是做的第一件事是创建一个小型测试应用程序。在这个应用程序中,对这两种情况进行一些计时测试,看看哪一种更快


依我看,追加500多个字符串条目肯定应该使用StringBuilder。

使用字符串进行连接可能会导致运行时的复杂性,其顺序为
O(n^2)


如果您使用
StringBuilder
,则需要进行的内存复制要少得多。使用
StringBuilder(int-capacity)
可以提高性能,前提是您可以估计最终的
字符串的大小。即使您不精确,您可能只需要将
StringBuilder的容量增加几倍,这也有助于提高性能。

StringBuilder减少分配和分配的数量,但会消耗额外的内存。如果使用得当,它可以完全消除编译器反复分配越来越大的字符串直到找到结果的需要

string result = "";
for(int i = 0; i != N; ++i)
{
   result = result + i.ToString();   // allocates a new string, then assigns it to result, which gets repeated N times
}
vs


我的方法一直是在连接4个或更多字符串时使用StringBuilder 或 当我不知道如何可能串联发生


字符串和StringBuilder实际上都是不可变的,StringBuilder内置了缓冲区,可以更有效地管理其大小。StringBuilder需要调整大小的时间是在堆上重新分配时。默认情况下,它的大小为16个字符,您可以在构造函数中进行设置

例如


StringBuilder sb=新StringBuilder(50)

为了澄清Gillian对4弦的看法,如果你有这样的想法:

string a,b,c,d;
 a = b + c + d;
var sb = new StringBuilder(int capacity);
然后使用字符串和加号操作符会更快。这是因为(就像Eric指出的Java一样),它在内部自动使用StringBuilder(实际上,它使用StringBuilder也使用的原语)

但是,如果您所做的更接近:

string a,b,c,d;
 a = a + b;
 a = a + c;
 a = a + d;
然后需要显式使用StringBuilder。Net不会在这里自动创建StringBuilder,因为这样做毫无意义。在每一行的末尾,“a”必须是一个(不可变)字符串,因此它必须在每一行上创建并处理一个StringBuilder。为了提高速度,在完成构建之前,您需要使用相同的StringBuilder:

string a,b,c,d;
StringBuilder e = new StringBuilder();
 e.Append(b);
 e.Append(c);
 e.Append(d);
 a = e.ToString();

这个基准测试表明,当组合3个或更少的字符串时,常规连接速度更快

StringBuilder可以显著提高内存使用率,尤其是在一起添加500个字符串的情况下

考虑以下示例:

string buffer = "The numbers are: ";
for( int i = 0; i < 5; i++)
{
    buffer += i.ToString();
}
return buffer;
通过将这五个数字添加到字符串的末尾,我们创建了13个字符串对象!其中12个是无用的!哇


StringBuilder解决了这个问题。它不是我们经常听到的“可变字符串”(在.NET中所有字符串都是不可变的)。它的工作原理是保留一个内部缓冲区,一个字符数组。调用Append()或AppendLine()将字符串添加到char数组末尾的空白处;如果数组太小,它将创建一个新的较大数组,并将缓冲区复制到该数组中。因此,在上面的示例中,StringBuilder可能只需要一个数组就可以包含字符串的所有5个附加项,具体取决于其缓冲区的大小。您可以告诉StringBuilder其缓冲区在构造函数中应该有多大。

我已经看到,在将StringBuilder的实例用于任何字符串存储之前,对其使用
EnsureCapacity(int capacity)
方法调用,可以显著提高性能。我通常在实例化后在代码行中调用它。它的效果与实例化
StringBuilder
的效果相同,如下所示:

string a,b,c,d;
 a = b + c + d;
var sb = new StringBuilder(int capacity);
此调用提前分配所需的内存,这导致在多个string myString = "Some stuff" + var1 + " more stuff" + var2 + " other stuff" .... etc... etc...;
StringBuilder sb = new StringBuilder();
sb.Append("Some Stuff");
sb.Append(var1);
sb.Append(" more stuff");
sb.Append(var2);
sb.Append("other stuff");
// etc.. etc.. etc..
string s = string.Empty;
StringBuilder sb = new StringBuilder();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 50000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();

Console.WriteLine("Beginning String + at " + DateTime.Now.ToString());

for (int i = 0; i <= 200000; i++)
{
    s = s + 'A';
}

Console.WriteLine("Finished String + at " + DateTime.Now.ToString());
Console.WriteLine();
Console.WriteLine("Beginning Sb append at " + DateTime.Now.ToString());

for (int i = 0; i <= 1000000; i++)
{
    sb.Append("A");
}
Console.WriteLine("Finished Sb append at " + DateTime.Now.ToString());

Console.ReadLine();
System.Diagnostics.Stopwatch time = new Stopwatch();
string test = string.Empty;
time.Start();
for (int i = 0; i < 100000; i++)
{
    test += i;
}
time.Stop();
System.Console.WriteLine("Using String concatenation: " + time.ElapsedMilliseconds + " milliseconds");
StringBuilder test1 = new StringBuilder();
time.Reset();
time.Start();
for (int i = 0; i < 100000; i++)
{
    test1.Append(i);
}
time.Stop();
System.Console.WriteLine("Using StringBuilder: " + time.ElapsedMilliseconds + " milliseconds");
using System;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // String Example

            string name = "Rehan";
            name = name + "Shah";
            name = name + "RS";
            name = name + "---";
            name = name + "I love to write programs.";

            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah RS --- I love to write programs."
        }
    }
}
using System;
using System.Text;

namespace StringVsStrigBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            // StringBuilder Example

            StringBuilder name = new StringBuilder();
            name.Append("Rehan");
            name.Append("Shah");
            name.Append("RS");
            name.Append("---");
            name.Append("I love to write programs.");


            // Now when I run this program this output will be look like this.
            // output : "Rehan Shah Rs --- I love to write programs."
        }
    }
}