zoukankan      html  css  js  c++  java
  • C#三种字符串拼接方法的效率对比

      C#字符串拼接的方法常用的有:StringBuilder、+、string.Format、List<string>。使用情况不同,效率不同。(+=将在+的方式中提到)

      1.+

      当有如下代码时:

    string sql = "update tableName set int1=" + int1.ToString() + ",int2=" + int2.ToString() + ",int3=" + int3.ToString() + " where id=" + id.ToString();
    

     编译器会将其优化为:

    string sql = string.Concat(new string[] { "update tableName set int1=", int1.ToString(), ",int2=", int2.ToString(), ",int3=", int3.ToString(), " where id=", id.ToString() });
    

     以下是Concat的实现:

    public static string Concat(params string[] values)
    {
    
        int totalLength = 0;
    
        if (values == null)
        {
    
            throw new ArgumentNullException("values");
    
        }
    
        string[] strArray = new string[values.Length];
    
        for (int i = 0; i < values.Length; i++)
        {
    
            string str = values[i];
    
            strArray[i] = (str == null) ? Empty : str;
    
            totalLength += strArray[i].Length;
    
            if (totalLength < 0)
            {
    
                throw new OutOfMemoryException();
    
            }
    
        }
    
        return ConcatArray(strArray, totalLength);
    
    }
    
    private static string ConcatArray(string[] values, int totalLength)
    {
    
        string dest = FastAllocateString(totalLength);
    
        int destPos = 0;
    
        for (int i = 0; i < values.Length; i++)
        {
    
            FillStringChecked(dest, destPos, values[i]);
    
            destPos += values[i].Length;
    
        }
    
        return dest;
    
    }
    
    private static unsafe void FillStringChecked(string dest, int destPos, string src)
    {
    
        int length = src.Length;
    
        if (length > (dest.Length - destPos))
        {
    
            throw new IndexOutOfRangeException();
    
        }
    
        fixed (char* chRef = &dest.m_firstChar)
        {
    
            fixed (char* chRef2 = &src.m_firstChar)
            {
    
                wstrcpy(chRef + destPos, chRef2, length);
    
            }
    
        }
    
    }
    

       该方法, 先计算目标字符串的长度,然后申请相应的空间,最后逐一复制,时间复杂度为o(n),常数为1。固定数量的字符串连接效率最高的是+。但是字符串的连+不要拆成多条语句,比如:

    string sql = "update tableName set int1=";
    
    sql += int1.ToString();
    
    sql += ...
    

       这样的代码,不会被优化为string.Concat,就变成了性能杀手,因为第i个字符串需要复制n-i次,时间复杂度就成了o(n^2)。

      2.StringBuilder

      如果字符串的数量不固定,就用StringBuilder,一般情况下它使用2n的空间来保证o(n)的整体时间复杂度,常数项接近于2。

      因为这个算法的实用与高效,.net类库里面有很多动态集合都采用这种牺牲空间换取时间的方式,一般来说效果还是不错的。

      3.string.Format

      它的底层是StringBuilder,所以其效率与StringBuiler相似。

      4.List<string>

      List<string>它可以转换为string[]后使用string.Concat或string.Join,很多时候效率比StringBuiler更高效。List与StringBuilder采用的是同样的动态集合算法,时间复杂度也是O(n),与StringBuilder不同的是:List的n是字符串的数量,复制的是字符串的引用;StringBuilder的n是字符串的长度,复制的数据。不同的特性决定的它们各自的适应环境,当子串比较大时建议使用List<string>,因为复制引用比复制数据划算。而当子串比较小,比如平均长度小于8,特别是一个一个的字符,建议使用StringBuilder。


     总结:

    1. 固定数量的字符串连接+的效率是最高的;
    2. 当字符串的数量不固定,并且子串的长度小于8,用StringBuiler的效率高些。
    3. 当字符串的数量不固定,并且子串的长度大于8,用List<string>的效率高些。
  • 相关阅读:
    免费的mail server
    opensuse 11.2/11.3安装vmware server 1.0.10笔记
    cisco IOS 免费下载的地方
    自动打开最快镜像站
    [ZT]MSSQL清空或者压缩日志的方法
    Cisco路由器的安全配置方案[zt]
    CISCO2821系列路由器恢复密码
    RTorrent User Guide
    Asp.Net发送邮件详解
    C#在线生成网页缩略图
  • 原文地址:https://www.cnblogs.com/hourglasser/p/3266991.html
Copyright © 2011-2022 走看看