字符串连接性能比较

老赵的一个字符串性能的系列文~

做个笔记~http://www.cnblogs.com/JeffreyZhao/archive/2009/11/26/string-concat-perf-1-benchmark.html

观点,结论性的东西:

  • 对于字符串数量比较少的情况(从数据上来看大约是5-6个),StringBuilder的性能并不比普通连接操作来的快。因此,在任何地方都使用StringBuilder是不恰当的做法
  • 我们的CharListBuilder虽然“模拟”了StringBuilder的情况,但还是慢了许多。说明StringBuilder的内部实现并非想象中那么简单。(开始想象的是:我们如果翻看《CLR via C#》,就会发现书中告诉我们说,在StringBuilder内部其实维护了一个类似于字符数组的结构,在不断添加字符串的过程中,这个数组会在需要的时候将容量加倍——这不就是List<T>的行为方式吗?)
  • CharListBuilder虽然比StringBuilder慢得多,但是在字符串数量多的情况下还是遥遥领先普通的字符串连接操作,说明不断生成新字符串的做法的确是性能杀手
  • 在字符串数量确定的情况下,String.Concat的性能要高于StringBuilder,而且其实字符串数量越多,差距越明显。

    String.Concat为什么这么快

    这便是String.Concat(string[])方法的全部实现,非常简单,清晰,但这也正是这个方法高效的原因所在。我们知道字符串是个不可变的对象,每次新建字符串都要开辟一块新空间。而String.Concat方法便将这个开辟新空间的代价减少到最小。因为在此之前已经确定结果的大小,因此直接创建一个“容器”即可,剩下的只是填充数据而已。既然可以不浪费任何一寸空间,也没有任何多余的操作,性能又怎会不高呢?

    • StringBuilder:如果能够确定目标字符串的最终长度,则可以使用StringBuilder。如果不能确定的话,也可以在一开始指定更大的容量,减少扩容的次数。
    代码
    private static string NewStringBuilder(int count)
    {
        var builder 
    = new StringBuilder(count * STR.Length);
        
    for (int i = 0; i < count; i++)
            builder.Append(STR);
        
    return builder.ToString();
    }
    • String.Concat:如果不能确定最终长度,但是能够确定字符串的个数(如这个场景),可以将它们放在一个数组中,并调用String.Concat进行连接。
    代码
        private static string StringConcat(int count)
        {
            var array 
    = new string[count];
            
    for (int i = 0; i < count; i++) array[i] = STR;
            
    return String.Concat(array);
        }

    • StringListBuilder:折衷方案,与String.Concat相比其优势在于无需确定字符串个数,与StringBuilder相比其优势在于“扩容”操作只需复制一些引用即可。
    代码
    public class StringListBuilder
    {
        
    private List<string> m_list;

        
    public StringListBuilder(int capacity)
        {
            
    this.m_list = new List<string>(capacity);
        }

        
    public StringListBuilder Append(string s)
        {
            
    this.m_list.Add(s);
            
    return this;
        }

        
    public string ToString()
        {
            
    return String.Concat(this.m_list.ToArray());
        }
    }

     

     

    代码
     private static string StringListBuilder(int count)
        {
            var builder 
    = new StringListBuilder(count);
            
    for (int i = 0; i < count; i++) builder.Append(STR);
            
    return builder.ToString();
        }

     

     

    posted @ 2009-12-27 21:57  Tmac_  阅读(247)  评论(2编辑  收藏  举报