10

我每秒收到大约 5 条消息。他们每个人都有一个字符串,我将它连接到一个包含所有接收到的消息的主字符串

    string _masterText = "";
    public void AddNewMessage(string text)  // this is going to be call at least 5 times/second
    {
        _masterText += text;    
    }

这是适当的方法吗?或者我应该使用 StringBuilder,比如:

    StringBuilder _masterText = new StringBuilder();
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second
    {
         _masterText.Append(text);  
    }

谢谢

4

6 回答 6

14

StringBuilder 通常被认为是更好的选择,但在这种情况下,我两者都不会使用。

即使使用 StringBuilder,以这种速度,底层字符缓冲区本身很快就会大到足以卡在大对象堆上。这将对需要保持运行一段时间的应用程序的运行状况造成问题。

相反,我会使用 a并为每条新消息System.Collections.Generic.List<string>调用它的方法。.Add()根据您对这些消息的处理方式,您可能还会发现另一种集合类型更合适(可能是 a Queue<string>),但这是您应该采取的方向。通过使用集合,每个单独的字符串使用的内存将不计入集合对象的大小。相反,每个字符串只会为引用添加几个字节。这将花费更长的时间来解决压缩大对象堆的问题。

如果切换到集合后仍有问题,可以使用,并将字符串写入磁盘。这样,您一次在 RAM 中永远不会有多个字符串。现在,您遇到问题的唯一方法是单个字符串是否为 85000 字节或更大。

于 2010-07-29T02:44:14.160 回答
8

请记住,String类是不可变的。无法更改字符串。当您“连接”字符串时,您实际上是在创建一个新字符串,并将原始字符串的内容复制到其中,然后添加新字符串的内容。

如果您要附加大字符串,这会很快开始使用内存。

于 2010-07-29T02:45:30.743 回答
3

每 200 毫秒不是一个非常费力的民意调查,不管 stringbuilder 总是更好。

于 2010-07-29T02:41:09.013 回答
1

如果您愿意阅读,我认为http://dotnetperls.com/stringbuilder-1上的讨论非常有用。查看有关速度和内存使用情况的真实指标的链接。

另外,请查看 Joel Spolsky 对“ Shlemeil the Painter's Algorithm ”的讨论。虽然他说的是 C 的strcat函数,但原理适用于 C# 对字符串的加号运算符。此外,它很适合笑。

一般来说,如果您正在快速执行附加操作或使用许多大字符串,我建议使用 StringBuilder。

于 2010-07-29T03:03:25.390 回答
0

StringBuilder 是你的好伙伴!

于 2010-07-29T02:41:53.717 回答
0

这也取决于场景。毫无疑问,与 stringbuilder 对象相比,添加通用列表更快。但是在从通用列表中检索数据期间,与 stringbuilder 对象相比,它会慢得多。

stringbuilder 将使用 _masterText.ToString() 快速返回,但使用通用列表,您可能必须使用迭代提取值。这将是一个昂贵的过程,例如:-

  for (int x = 0; x < 100; x++)
    {
      Label3.Text += gen_list[x];
    }

或者你可以试试

Label3.Text = string.Join("", gen_list.ToArray());

那么检索操作将变得更慢且成本更高,并且您很容易注意到 CPU 峰值。

于 2010-07-29T09:44:42.920 回答