c#基础系列之System.String的深入理解

2020-01-05 09:21:48丽君
  • 如果程序经常会对比重复度比较高的字符串,这会造成性能上的影响,因为对比字符串是要经过几个步骤的。为此CLR引入了一个字符串重用的技术,学名叫做‘字符串留用'。原理就是:CLR会在初始化的时候创建一个内部的哈希表,key是字符串,value就是留用字符串在托管堆上的引用。
    String类型提供了两个静态方法来操作这个哈希表:

    String.Intern

    String.IsInterned

    具体请查看msdn(https://www.easck.com/zh-cn/library/system.string.isinterned(v=vs.110).aspx)

    但是c#编译器默认是不开启字符串留用功能的,因为如果程序大量把字符串留用,应用程序总体性能可能会变得更慢。(微软也是挺纠结的,程序员TMD的更纠结)

    如果我们的程序中有很多个一模一样值的常量字符串, c#的编译器会在编译期间把这些字符串合并为一个并写入模块的元数据中,然后修改所有引用该字符串的代码。这也是一种字符串重用技术,学名‘字符串池'。这意味着什么呢?这意味着所有值相同的常量字符串其实引用的是同一个内存地址的实例,在相同值非常多的情况下能显著提高性能和节省大量内存。

    
    string s1 = "hello 大菜";
    string s2 = "hello 大菜";
    unsafe
    {
     fixed (char* p = s1)
     {
      Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
    
     }
     fixed (char* p = s2)
     {
      Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
    
     }
    } 

    输出结果:

    字符串地址= 0x80002d84