1.前言
string是属于引用类型的,这个大家都知道吧?但是平常在使用的过程中,发现它还是拥有一些值类型的特征的,这到底是为什么呢?
原因就是.Net考虑到假如大量的操作string对象的时候,大量对引用对象进行操作的时候,性能肯定不如值类型来的爽快。.Net为了提高这个性能,提供了一个专门的解决方案:字符串驻留池!
2.正文
先让我们来看一段代码:
string str1 = "aa"; string str2 = "a" + "a"; Console.WriteLine(ReferenceEquals(str1, str2)); //print:true
这str1跟str2的内存指向地址居然是一模一样的!
原因是.Net在CLR内部维护了一个Hash表(其实就是前文说的字符串驻留池),key为字符串内容,值就是所指向的托管堆的地址;当初始化创建了一个新的字符串的时候,.Net就会去这个Hash表中搜索是否有相同的值,如果key相同,就会把已经存在的字符串的地址值赋给新创建的字符串,如果不存在则重新分配地址,这就是为什么上面这个代码的内存为true。
再让我们来看另外一段代码:
string str3 = "ab"; string str4 = "a"; str4 += "b"; Console.WriteLine(ReferenceEquals(str3, str4));//print :false
之所以出现了false,请注意上一栏的关键字“初始化创建”,当字符串是动态创建的时候,.Net并不会去Hash表中搜索是否有创建,而是直接创建;
假如想对上面的代码优化一下并且对性能有更(xian)高(de)追(dan)求(teng),我们可以手动将这个字符串加入到字符串驻留池中进行对比
string str3 = "ab"; string str4 = "a"; str4 += "b"; str4 = string.Intern(str4);//Intern:它会去字符串驻留池中搜索,假如找寻到的话则返回对应的地址 Console.WriteLine(ReferenceEquals(str3, str4));//print :true
3.总结
最后对string下点结论:
1.string在clr中不是用newobj指令创建,而是用ldstr指令创建!而且string拥有值类型的特征,但是在内存上是引用类型,存在托管堆上面;
2.string是sealed修饰的,所以不能被子类集成;
3.当创建内容相同的时候,string是指向同一地址的,而且每次操作string都会生成新的地址(string的恒定性);
4.对于大量拼接的话还是使用StringBuilder,它是动态的不像string是恒定的,但就是创建StringBuilder代价比较大,所以小拼接用string在性能上可能还更好!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!
Spring的DispatcherServlet使用了特殊的bean来处理请求、渲染视图等,这些特定的bean是Spring MVC框架的一部分。如果你想指定使用哪个特定的bean,你可以在web应用上下文WebApplicationContext中简单地配置它们。当然这只是可选的,Spring MVC维护了一个默认的bean列表,如果你没有进行特别的配置,框架将会使用默认的bean。下一小节会介
局部变量 局部变量只在代码块或一个函数里有效 (参考函数里的局部变量) 环境变量这种变量会影响Shell的行为和用户接口 在大多数情况下,每个进程都会有一个"环境表", 它由一组由进程使用的环境变量组成。这样看来,Shell看起来和其他的进程一样。 每次一个Shell启动时,它都会创建新的合适的环境变量。如果它增加或是更新一个环境变量,都会使这个Shell的环境表得到更新(译者注:换句话说,更改或
22.2.1 WebApplicationContext中的特殊Bean类型 Spring的DispatcherServlet使用特殊的bean来处理请求并渲染合适的视图,这些bean是Spring MVC的一部分。可以通过在WebApplicationContext中进行简单配置选择这些特殊bean中的一个或多个来使用。不过,最初并不需要这样做,因为如果没有进行任何配置,Spring MVC维护
本文向大家介绍详解Angular.js指令中scope类型的几种特殊情况,包括了详解Angular.js指令中scope类型的几种特殊情况的使用技巧和注意事项,需要的朋友参考一下 前言 大家都知道在默认情况下,指令应该访问父作用域.如果我们对指令暴露了父控制器的scope,那么指令就可以自由的修改scope属性.在一些情况下,你的指令可能想要添加一些只有内部可以使用的属性和函数,如果我们都在父作用
本文向大家介绍详解C#中的string与String,包括了详解C#中的string与String的使用技巧和注意事项,需要的朋友参考一下 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string 与原义 string string 的转义序列 格式化字符串 操作子字符串 字符串的 null 与 ""(空) 可提高性能的 String
主要内容:1 Redis的数据类型,2 Redis key,2.1 二进制安全与SDS,3 Redis String,3.1 数值原子操作,3.2 批量操作,3.3 key通用操作,3.5 彩蛋详细介绍了Redis的key和String数据类型的底层原理,以及最基本的使用方式。 1 Redis的数据类型 Redis 不是一个普通的key-value存储服务器,它实际上是一个数据结构服务器,支持不同类型的值,在Redis中值不仅限于简单的字符串,还可以包含更复杂的数据结构。 以下是Redis支持的