C# 字符串的三种拼接方法性能比较

1. 按

本文主要用于介绍C#中字符串拼接的三种方法:String 的+concat方法 以及 StringBuilder( or StringBuffer) 的append方法之间的性能差异。

2. 字符串拼接的三种方法

  1. 加号+
  2. concat方法;(用法示例可参考:https://blog.csdn.net/COCO56/article/details/102531010
  3. StringBuilder(或StringBuffer)的append方法;

一般来讲,拼接速度:3>>2>1,即方法3远快于方法2,方法2略快于方法1。

3. 原因

  1. 对+号来说
    每趟循环都会创建一个StringBuilder对象 ;
    每次执行完毕都会调用toString方法将其转换为字符串 。
    不适用于循环操作。
    如对于:

    String str = "My name is ";
    str = str + "csdn";
    

    相当于 str = new StringBuilder(str).append(“csdn”).toString();
    语句执行完之后,总共有三个对象。

  2. concat()方法:
    concat源代码:

     public String concat(String str) {
            // 追加的字符串长度
            int otherLen = str.length();
            // 如果追加的字符串长度为0,则不做修改,直接返回原字符串
            if (otherLen == 0) {
                return this;
            }
            // 获取原字符串的字符数组value的长度
            int len = value.length;
            // 将原字符串的字符数组value放到buf字符数组中
            char buf[] = Arrays.copyOf(value, len + otherLen);
            // 将追加的字符串转化成字符数组,添加到buf中
            str.getChars(buf, len);
            // 产生一个新的字符串并返回
            return new String(buf, true);
        }
    

    整体是一个数组的拷贝,虽然在内存中是处理都是原子性操作,速度非常快,但是,最后的return语句创建一个新String对象,也就是每次concat操作都会创建一个新的String对象,这也是限制concat方法速度的原因。

  3. append()方法
    append源代码:

    public AbstractStringBuilder append(String str) {
            // 如果是null值,则把null作为字符串处理
            if (str == null)
                return appendNull();
            int len = str.length();
            // 追加后的字符数组长度是否超过当前值
            ensureCapacityInternal(count + len);
            // 字符串复制到目标数组
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }
       private AbstractStringBuilder appendNull() {
            int c = count;
            ensureCapacityInternal(c + 4);
            final char[] value = this.value;
            value[c++] = 'n';
            value[c++] = 'u';
            value[c++] = 'l';
            value[c++] = 'l';
            count = c;
            return this;
        }
        private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            if (minimumCapacity - value.length > 0)
                expandCapacity(minimumCapacity);  // 加长,并作数组拷贝
        }
    

    整个append方法都在做字符数组的处理,加长,拷贝等,这些都是基本的数据处理,整个方法内并没有生成对象。只是最后toString返回一个对象而已。需要注意的是,append()方法返回的是一个StringBuilder(or StringBuffer)对象实例。

  4. 总结
    大多数情况下,使用“+”即可满足需求,但是当在频繁进行字符串的运算(如拼接、替换、删除等),或者在系统性能临界的时候,我们可以考虑使用concat()或append()方法。

4. 实际测试

正在测试各方法在拼接0到99999之间的数字为一个长字符串的用时:
加号用时:00:00:17.0903268
concat()方法用时:00:00:16.9477968
StringBuilder的append()方法用时:00:00:00.0149635

源码:

using System;
using System.Diagnostics;
using System.Text;

namespace _2_6_字符串拼接性能比较
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("正在测试各方法在拼接0到99999之间的数字为一个长字符串的用时:");
            testAdd();
            testConcat();
            testAppend();

            Console.WriteLine("\nPress any key to quit.");
            Console.ReadKey();
        }

        static void testAdd()
        {
            //需要不断地开辟存储空间
            string str = "";
            //创建一个计时器,用于记录程序运行时间
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000; i++)
            {
                str += i;
            }
            sw.Stop();
            //Console.WriteLine(str);
            Console.Write("加号用时:");
            Console.WriteLine(sw.Elapsed);
        }

        static void testConcat()
        {
            string str = "";
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            for (int i = 0; i < 100000; i++)
            {
                str = String.Concat(str, i);
            }
            sw.Stop();
            //Console.WriteLine(str);
            Console.Write("concat()方法用时:");
            Console.WriteLine(sw.Elapsed);
        }

        static void testAppend()
        {
            //没有开空间,玩的是同一块内存
            StringBuilder sb = new StringBuilder();
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            for (int i = 0; i < 100000; i++)
            {
                sb.Append(i);
            }
            sw.Stop();
            //Console.WriteLine(sb.ToString());
            Console.Write("StringBuilder的append()方法用时:");
            Console.WriteLine(sw.Elapsed);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

COCO56(徐可可)

建议微信红包:xucoco56

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值