字符串具有值类型的特点对字符串,对同一个字符串大量修改或者对多个引用赋值同一个字符串对象时会产生大量的临时字符串对象,影响性能,但是CLR为我们做了一些工作来消除这些弊端。

     对同一个字符串大量修改的问题可以使用StringBulid来解决这个问题,看看下面这个例子:

private string item = "string";

  public void TestStringBuild()

  {

   long sbStart = DateTime.Now.Ticks;

   UseStrigBuilder(1000);

   long sbEnd = DateTime.Now.Ticks;

   Console.WriteLine("使用StringBuilder消耗时间: "+(sbEnd-sbStart).ToString());

   long strStart = DateTime.Now.Ticks;

   UseString(1000);

   long strEnd = DateTime.Now.Ticks;

   Console.WriteLine("使用String消耗时间:"+(strEnd-strStart).ToString());

}

  public string UseStrigBuilder(int number)

  {

   StringBuilder sb = new StringBuilder();

   for(int i = 0; i < number; i++)

   {

    sb.Append(item);

    

   }

   sb.Remove(sb.Length-1 , 1);

   return sb.ToString();

  }

  public string UseString(int number)

  {

   string result = "";

   for(int i = 0; i < number; i++)

   {

    result += item;

   }

   return result;

  }

输出结果为
     

注:DateTime.Now.Ticks:此属性的值表示自 0001 年 1 月 1 日午夜 12:00:00 以来已经过的时间的以 100 毫微秒为间隔的间隔数。 

就是说这1000次循环如果使用StringBuilder的话节省了15625000毫秒的时间。

      第二个问题,对多个引用赋值同一个字符串对象,CLR的解决方法更加巧妙。在默认情况下CLR会使用字符串池的机制,CLR启动的时候,在内部创建一个容器,它以键值对的形式存在,键值是字符串对象内容,值是字符串在托管堆上的引用,当一个新的字符串对象创建的时候CLR检查在这些值中是否已经存在这个字符串对象,如果已经存在就返回对应的值,也就是在托管堆中的引用,如果不存在就在这个容器中中开辟空间存放这个字符串,返回在他的引用。

      这里还是用一段代码来说明:

  public void StringPoolTest()

  {

   string str1 = "789";

   string str2 = "789";

   Console.WriteLine(Object.ReferenceEquals(str1 , str2));

   string str3 = "7" + "8" + "9";

   Console.WriteLine(Object.ReferenceEquals(str1, str3));

   char[] chars = new char[] { '7', '8', '9' };

   string str4 = new string(chars);

   Console.WriteLine(object.ReferenceEquals(str1 , str4));

  }

输出结果:


前两次都输出true说明str1和str2都指向同一个堆引用,最后一个输出false是因为它使用new关键字进行内存分配,字符串池机制不起作用。

这里注意string str3 = "7" + "8" + "9";这个语句在正常的情况下只分配了一次内存,这个也是CLR的优化,在这里就没有分配内存了,因为str1这里已经分配好了。

作者:Tyler
Ning
 

出处:http://www.cnblogs.com/tylerdonet/ 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com 联系我,非常感谢。

我不知道的C#—字符串池机制的更多相关文章

  1. 不得不知道的Python字符串编码相关的知识

    开发经常会遇到各种字符串编码的问题,例如报错SyntaxError: Non-ASCII character 'ascii' codec can't encode characters in posi ...

  2. 你可能不知道的jvm的类加载机制

    引言:在java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 加载:查找并加载类的二进制数据(class文件加载到内存中) 连接:a 验证:确保被加载类的正确性. b准备:为类的静态 ...

  3. 【转载】不得不知道的Python字符串编码相关的知识

    原文地址:http://www.cnblogs.com/Xjng/p/5093905.html 开发经常会遇到各种字符串编码的问题,例如报错SyntaxError: Non-ASCII charact ...

  4. 你所不知道的Python | 字符串连接的秘密

    字符串连接,就是将2个或以上的字符串合并成一个,看上去连接字符串是一个非常基础的小问题,但是在Python中,我们可以用多种方式实现字符串的连接,稍有不慎就有可能因为选择不当而给程序带来性能损失. 方 ...

  5. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  6. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  7. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  8. 1.字符串池化(intern)机制及拓展学习

    1.字符串intern机制 用了这么久的python,时刻和字符串打交道,直到遇到下面的情况: a = "hello" b = "hello" print(a ...

  9. 你所不知道的setTimeout

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...

随机推荐

  1. js中变量的声明

    大家都知道js中变量的声明是要提前的,下面有4个样例: 1.if(!"t" in window){  var t = 1; }       alert(t);答案是undefine ...

  2. 【BZOJ3566】[SHOI2014]概率充电器 期望+树形DP

    [BZOJ3566][SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线 ...

  3. 红黑树深入剖析及Java实现(转自知乎美团点评技术团队)

    作者:美团点评技术团队 链接:https://zhuanlan.zhihu.com/p/24367771 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 红黑树是平衡 ...

  4. ElasticSearch(十三) bulk api奇特的json格式的原因

    bulk api的语法 正常的语法: {"action": {"meta"}}\n {"data"}\n {"action&quo ...

  5. (linux)struct inode 和 struct file

    转自:http://www.cnblogs.com/QJohnson/archive/2011/06/24/2089414.html 1.struct inode──字符设备驱动相关的重要结构介绍 内 ...

  6. hihocoder #1122 二分图二•二分图最大匹配之匈牙利算法(*【模板】应用 )

    梳理整个算法: 1. 依次枚举每一个点i: 2. 若点i尚未匹配,则以此点为起点查询一次交错路径. 最后即可得到最大匹配数. 在这个基础上仍然有两个可以优化的地方: 1.对于点的枚举:当我们枚举了所有 ...

  7. CSU 1554 SG Value —— 思维

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1554 Description The SG value of a set (mult ...

  8. ansible 基础知识

    英文官网,值得拥有! http://docs.ansible.com/ansible/list_of_files_modules.html# 摘自: http://blog.csdn.net/b624 ...

  9. EnumDescription

    using System; using System.Reflection; using System.Collections; using System.Collections.Generic; n ...

  10. python 二分法例子及冒泡排序

    #!/usr/bin/env python #-*- coding:utf-8 -*- def binary_search(source_data,find_nu): mid = len(source ...