C#区分string、StringBuilder

目录

区分string和StringBuilder

1.可变性

1)string

2)StringBuilder

2.性能

1)string

2)StringBuilder

3.线程安全

1)string

2)StringBuilder

总结


       本篇文章来区分string、StringBuilder,主要从可变性,性能,线程安全三个方面进行比较。

区分string和StringBuilder

1.可变性

1)string

string不可变。每次修改都会创建一个新的字符串对象。适合于不需要频繁修改的场景,如简单的字符串拼接和读取。

string greeting = "Hello";
string name = "World";
//产生的结果,通常会被优化为一个string对象"Hello, World!"
string message = greeting + ", " + name + "!";

总共有3个string对象:"Hello","World","Hello, World!"

2)StringBuilder

StringBuilder可变。在原有对象上进行修改,适合于频繁修改的场景,如在循环中拼接字符串。

StringBuilder sb = new StringBuilder();//using System.Text;
sb.Append("Hello");
sb.Append(",");
sb.Append("Hello");
sb.Append("!");
string fullName = sb.ToString();//"Hello, World!"

总共有1个string对象,最终为"Hello, World!"。

2.性能

1)string

string性能低。在频繁拼接或修改时,性能会下降,因为每次修改都会生成新对象,导致内存使用增加和垃圾回收压力。

2)StringBuilder

StringBuilder性能高。对于大量字符串操作,如多次拼接,性能更优,因为它避免了频繁的内存分配和垃圾回收。

3.线程安全

1)string

string线程安全。由于是不可变的,每次修改都会创建新对象,因此在多线程环境中,string是线程安全的,因为多个线程读取同一string对象不会发生冲突,不需要额外的同步机制。

2)StringBuilder

StringBuilder线程不安全。多个线程同时修改同一个StringBuilder对象可能会导致数据竞争。如果需要在多线程环境中使用 StringBuilder,通常需要进行同步控制,如使用锁 (lock) 来确保线程安全。

using UnityEngine;
using System.Text;
using System.Threading;

public class StringBuilderTest:MonoBehaviour
{
    private static StringBuilder stringBuilder = new StringBuilder();

    private void Start()
    {
        Test();
    }

    public void Test()
    {
        Thread thread1 = new Thread(AppendText);
        Thread thread2 = new Thread(AppendText);

        thread1.Start();
        thread2.Start();

        thread1.Join();//thread1.Join()阻塞主线程,直到thread1完成
        thread2.Join();

        Debug.Log(stringBuilder.ToString());//0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
    }

    private void AppendText()
    {
        //stringBuilder对象作为锁对象。
        //在进入lock代码块时,当前线程会尝试获得对stringBuilder的独占锁。
        //如果另一个线程已经持有stringBuilder的锁,当前线程会等待,直到其他线程释放锁。一旦锁被释放,当前线程可以获得锁并进入lock代码块。
        lock (stringBuilder)
        {
            for (int i = 0; i < 10; i++)
            {
                stringBuilder.Append(i + " ");
            }
        }
    }
}

       将脚本挂载到物体上,运行,进行测试。

       thread1和thread2都会启动并调用AppendText方法,两个线程都尝试对stringBuilder进行操作。由于lock (stringBuilder),在任意时刻只有一个线程能够进入lock代码块。每个线程在其锁定区域内会向stringBuilder中追加10个数字(从 0 到 9)。lock确保了对stringBuilder的操作是线程安全的,两个线程会按照顺序各自向stringBuilder追加0到9的数字,结果是两个序列合并在一起,可能是“0 1 2 3 4 5 6 7 8 9 ”出现一次,然后是另一组“0 1 2 3 4 5 6 7 8 9 ”,但顺序可能不同,这取决于线程的调度顺序。

总结

1)string:不可变,性能更低,但线程安全。适合于简单的字符串拼接和读取。

2)StringBuilder:可变,性能更高,但线程不安全。适合于复杂、频繁的字符串操作,且需要额外处理线程安全问题。

补充一下,StringBuffer属于Java概念,可变、线程安全,用于处理多线程环境中的字符串操作。

       好了,今天的分享到这里就结束啦,希望对你有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值