String 和 StringBuilder 类型

尽管 StringBuilder 和 String 都表示字符序列,但它们的实现方式不同。 

String 是不可变类型。 也就是说,出现的用于修改对象的每个操作 String 实际上都会创建一个新的字符串。

对于执行大量字符串操作的例程 (例如在循环中多次修改字符串的应用程序) ,重复修改字符串可能会显著降低性能。 替代方法是使用 StringBuilder ,它是一个可变字符串类。 可变性是指在创建类的实例后,可以通过追加、移除、替换或插入字符来修改它。 StringBuilder对象维护缓冲区以容纳对字符串的扩展。 如果空间可用,则会将新数据追加到缓冲区;否则,将分配一个新的更大的缓冲区,将原始缓冲区中的数据复制到新缓冲区,然后将新数据追加到新缓冲区。

尽管 StringBuilder 类通常比 String 类提供更好的性能,但你不应在 String 每次需要操作字符串时自动将替换为StringBuilder 。 性能取决于字符串的大小、要为新字符串分配的内存量、正在执行应用程序的系统以及操作的类型。 应该准备好测试应用程序,以确定实际是否 StringBuilder 提供显著的性能改进。

请考虑在以下情况下使用 String 类:

  • 当你的应用将对字符串进行的更改数量很小时。 在这些情况下, StringBuilder 可能会提供可忽略不及或不会提高性能。

  • 当你执行固定数量的串联操作时,尤其是字符串文本。 在这种情况下,编译器可能会将串联操作合并为单个操作。

  • 在生成字符串时,必须执行大量的搜索操作。 StringBuilder类缺少搜索方法,如 IndexOf 或 StartsWith 。 StringBuilder对于这些操作,必须将对象转换为 String ,这可能会使使用不会带来性能优势 StringBuilder 。 有关详细信息,请参阅在 StringBuilder 对象中搜索文本 部分。

请考虑在以下情况下使用 StringBuilder 类:

  • 如果希望应用在设计时对字符串进行未知数量的更改 (例如,当你使用循环来连接包含用户输入) 的随机数量的字符串时。

  • 希望应用对字符串进行大量更改时。


StringBuilder 的工作方式

StringBuilder.Length属性指示对象当前包含的字符数 StringBuilder 。 如果向对象添加字符 StringBuilder ,则其长度将增加,直到它等于属性的大小 StringBuilder.Capacity ,该大小定义对象可以包含的字符数。 如果添加的字符数导致对象的长度 StringBuilder 超过其当前容量,则分配新内存,属性的值 Capacity 翻倍,新字符将添加到 StringBuilder 对象中,并 Length 调整其属性。 对象的额外内存 StringBuilder 会动态分配,直到达到属性定义的值 StringBuilder.MaxCapacity 。 达到最大容量时,不能为该对象分配更多的内存 StringBuilder ,尝试添加字符或将其扩展到超出其最大容量后,会引发 ArgumentOutOfRangeException 或 OutOfMemoryException 例外。

 

下面的示例演示了 StringBuilder 对象如何分配新内存并动态增加其容量,因为分配给对象的字符串会展开。 该代码 StringBuilder 通过调用默认 (无参数) 构造函数来创建对象。 此对象的默认容量为16个字符,其最大容量超过2000000000个字符。 追加字符串 "This is a 句子"。 导致新的内存分配,因为字符串长度 (19 个字符) 超过对象的默认容量 StringBuilder 。 对象的容量长度为32个字符,添加新字符串,并且对象的长度现在等于19个字符。 然后,该代码将追加字符串 "This is 其他句子"。 对象的值 StringBuilder 11 次。 每当追加操作导致对象的长度 StringBuilder 超过其容量时,其现有容量就会加倍, Append 操作成功。

using System;
using System.Reflection;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb = new StringBuilder();
      ShowSBInfo(sb);
      sb.Append("This is a sentence.");
      ShowSBInfo(sb);
      for (int ctr = 0; ctr <= 10; ctr++) {
         sb.Append("This is an additional sentence.");
         ShowSBInfo(sb);
      }   
   }
   
   private static void ShowSBInfo(StringBuilder sb)
   {
      foreach (var prop in sb.GetType().GetProperties()) {
         if (prop.GetIndexParameters().Length == 0)
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
      }
      Console.WriteLine();
   }
}
// The example displays the following output:
//    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
//    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
//    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值