千家信息网

.Net字符暂存池的示例分析

发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,这篇文章将为大家详细讲解有关.Net字符暂存池的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。字符串在.Net中既有值类型的特点又有引用类型的特点,字符类型
千家信息网最后更新 2024年11月17日.Net字符暂存池的示例分析

这篇文章将为大家详细讲解有关.Net字符暂存池的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

字符串在.Net中既有值类型的特点又有引用类型的特点,字符类型也称作为不可变对象类型,字符串类型在使用上可以说占很大的比例,每次使用的时候都要重新开辟一个新的空间,这样会大量消耗内存,所以微软给我们一个名为String Intern Pool的字符暂存池,我在重复使用这个字符串的时候不需要重新开辟一个新的空间,只需要从这个池子里面获取即可。

我们在新建一个字符的时候,首先去暂存池获取有没有这个字符,如果没有则把这个新的字符串保存到暂存池。

下面是string类的两个方法

        //        // 摘要:        //     检索系统对指定 System.String 的引用。        //        // 参数:        //   str:        //     要在暂存池中搜索的字符串。        //        // 返回结果:        //     如果暂存了 str,则返回系统对其的引用;否则返回对值为 str 的字符串的新引用。        //        // 异常:        //   T:System.ArgumentNullException:        //     str 为 null。        [SecuritySafeCritical]        public static String Intern(String str);        //        // 摘要:        //     检索对指定 System.String 的引用。        //        // 参数:        //   str:        //     要在暂存池中搜索的字符串。        //        // 返回结果:        //     如果 str 在公共语言运行时的暂存池中,则返回对它的引用;否则返回 null。        //        // 异常:        //   T:System.ArgumentNullException:        //     str 为 null。        [SecuritySafeCritical]        public static String IsInterned(String str);

字符串暂存池(intern pool)其实是一张哈希表,键是字符串字面量,值是托管堆上字符串对象的引用。在加载程序集时,不同版本的CLR对于是否留用程序集元数据中的字符串字面量(在编译时值已确定)不尽相同。

我们在给string类型变量分配字面量值时,CLR会先到字符串池中看下有没有完全相同的字符串(区分大小写),若有则返回对应的引用,若无,则创建新对象并添加到字符串池中返回引用。但若在运行时(如,使用new关键字)来给字符串变量分配值则不会使用字符串池。

string a = "abc";string b = "abc";string c = new string(new char[] { 'a', 'b', 'c' });
Console.WriteLine(a.Equals(b));Console.WriteLine(a.Equals(c));
Console.WriteLine(object.ReferenceEquals(a, b));//trueConsole.WriteLine(object.ReferenceEquals(a, c));//false

下面我们针对这个来测试一波性能

1.测试十万条数据字符拼接

2.测试不同字符串拼接

3.测试相同字符拼接

代码如下:

//针对相同字符拼接Stopwatch sw1 = new Stopwatch();string a = "a";string b = string.Empty;sw1.Start();for (int i = 0; i < 100_000; i++){    b += a;}sw1.Stop();Console.WriteLine($"相同字符拼接消耗时间={sw1.ElapsedMilliseconds}");//针对不同字符拼接Stopwatch sw2 = new Stopwatch();string c = string.Empty;sw2.Start();for (int i = 0; i < 100_000; i++){    //i.ToString();    c += i.ToString();}sw2.Stop();Console.WriteLine($"不同字符拼接消耗时间={sw2.ElapsedMilliseconds}");//检测装箱的时间Stopwatch sw3 = new Stopwatch();string d = string.Empty;sw3.Start();for (int i = 0; i < 100_000; i++){    i.ToString();}sw3.Stop();Console.WriteLine($"检测装箱消耗的时间{sw3.ElapsedMilliseconds}");

结果如下

相同字符拼接消耗时间=1695不同字符拼接消耗时间=26925检测装箱消耗的时间12

总结:net中的字符串存在方式多种多样,我们要分清是运行是创建还是编译时创建,我们在程序中,经常会用到字符串类型,对于我们常用的字符串应该使用常量来定义,以保证它的复用性。

关于".Net字符暂存池的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0