特殊的string类型
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在性能上可能还更好!
还有最后一个最后,卖点小广告:深圳地区招聘.Net开发工程师(医疗方向),有兴趣的小伙伴可以发送简历 (入职后我们将推荐奖金拿去上梅林的潮兴火锅吃了吧~)
特殊的string类型的更多相关文章
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- 每日一记-mybatis碰到的疑惑:String类型可以传入多个参数吗
碰到一个觉得很疑惑的问题,Mybatis的parameterType为String类型的时候,能够接收多个参数的吗? 背景 初学Mybatis的时候,看的教程和书籍上都是在说基本的数据类型如:int. ...
- C#string类型总结
字符串的特性:不可变性,每对字符串做拼接或者重新赋值之类的操作,都会在内存中产生一个新的实例. 所以说,在.Net平台下,如果你对一个字符串进行大量的拼接赋值等操作,会产生大量的垃圾. --- ...
- 把《c++ primer》读薄(3-1 标准库string类型初探)
督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 问题1:养成一个好习惯,在头文件中只定义确实需要的东西 using namespace std; //建议需要什么再using声 ...
- 【原创】Java和C#下String类型中的==和equals的原理与区别
一.Java下 1.几个例子 public static void main(String[] arge) { String str1 = new String("1234"); ...
- String类型的属性和方法
× 目录 [1]属性 [2]对象通用方法 [3]访问字符方法[4]字符串拼接[5]创建子串方法[6]大小写转换[7]查找子串位置[8]正则匹配方法[9]去除首尾空格[10]字符串比较 前面的话 前面已 ...
- String类型传值以及对象传值
package Virtual; class Stan{ String mm = "hello"; } class Virtual { public static void mai ...
- java动手动脑和课后实验型问题String类型
1.请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? true true false 总结: 使用new关键字创建字符串对象时, 每次申请 ...
- java内存分配和String类型的深度解析
[尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...
- javascript类型系统——字符串String类型
× 目录 [1]定义 [2]引号 [3]反斜线[4]特点[5]转字符串 前面的话 javascript没有表示单个字符的字符型,只有字符串String类型,字符型相当于仅包含一个字符的字符串 字符串S ...
随机推荐
- leetcode-005 reorder list
1 package leetcode; public class ReOrderList { public void reorderList(ListNode head) { if(head==nul ...
- BootStrap TreeView使用示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- C语言-表达式
表达式是使用运算符连接起来的式子,C语言中的表达式有以下几种: 1.算数运算符 + - * / % 2.赋值运算符 += -= *= /= %= 3.自增.自减 ++ -- a++为先 ...
- UVa 10911 - Forming Quiz Teams
题目大意:给出2*n个点,将这些点配成n对,使得所有点对中两点的距离之和尽量小. 用一个整数的二进制形式表示一个集合的子集,以每个集合为状态进行状态转移.具体参见<算法竞赛入门经典>9.5 ...
- UVa 793 - Network Connections
题目大意:给出计算机之间的连接配置,询问某两台计算机是否相连.判断两个点是否在同一个连通分量里,用并查集处理. #include <cstdio> #define MAXN 1000000 ...
- JAVA文件的两种读取方法和三种写入方法
在使用java对文件进行读写操作时,有多种方法可以使用,但不同的方法有不同的性能. 此文对常用的读写方法进行了整理,以备不时之需. 1.文件的读取 主要介绍两种常用的读取方法.按行读取和按字符块读取. ...
- IM 之 融云
官方网站:http://www.rongcloud.cn 官方开发文档:http://www.rongcloud.cn/docs/ IM 融云 之 开发基础概念 IM 融云 之 通讯能力库API IM ...
- Jenkins中deploy插件的deploy war/ear to a container与deploy artifacts to maven reepository区别
deploy war/ear to a container:发布war包到服务器 deploy artifacts to maven reepository:发布到maven服务器
- iOS 之 深复制、浅复制
深复制不仅复制对象本身,对象持有的属性对象也做了复制. 浅复制之复制对象本身,不对里面的属性进行复制.
- php将图片以二进制保存到mysql数据库并显示
一.存储图片的数据表结构: -- -- 表的结构 `image` -- CREATE TABLE IF NOT EXISTS `image` ( `id` int(3) NOT NULL AUTO_I ...