简单看看这两个类 String和StringBuilder
我记得以前在园子里面讨论这两个类的文章有很多很多,并且还拿出了很多的测试报告,在什么情况下,谁比谁快,在什么情况下,该用谁
不该用谁等等这些,我这里就不比较了,我就简单看看他们里面的内部实现,那就先看看String吧。
一:String类
说到String类,资料上都说是存在于堆上的一个不可CURD的一个不可变的字符集,当然看到这句话之后就想要看看是不是这样的,然后就
好奇的写了以下代码。
class Program
{
static void Main(string[] args)
{
string s = "";
}
}

从上面的IL中也就仅仅发现一个ldstr指令,看得出clr把string做成了基元类型,也就没看到它具体转换成了什么样的方法,是不是调用了string
的构造函数,这个也不清楚,也就不知道具体怎么把这个有序字符集放到堆中,不过办法还是有的,我们随便挑一个方法看看,比如简单一点的
substring,我们看看它的源代码。

然后我们找到了一个核心的方法,这个internalSubstring里面定义了两个指针ptr和ptr2,ptr则指向新申请的内存块的首地址,ptr2则指向原始
字符串的首地址,最后将ptr2的位置偏移startindex个位置,最后我们就找到了终极方法string.wstrcpy。

在string.wstrcpy方法里面,虽然看的迷迷糊糊,不过还是能看到类似这样的偏移操作,一点一点的将smem地址上的字符赋值给dmem中,
确实也就说明了在堆上是有序的字符集。

同样在上面的源代码中来说,substring操作并没有对原始字符串进行修改,而是把截取的值放到新申请的内存地址空间中,这也就说明了字符
串是不可修改的说法,当然如果设计者真的要做到原位修改,那肯定也是能做到的,为了佐证下,我再举一个经常用到的concat方法,不过在
FastAllocateString方法中,并没有看到他的源代码,所以只能说根据length申请合适的空间。

所以结论出来了: 当你对字符串进行大量操作的时候,会产生很多的新的字符串,这些字符串会大量零碎的占据着堆空间,大多都是生存期较短
的,所以一般都是在堆的第一代上,所以会对gc产生了比较大回收压力。
二:StringBuilder
看这个类的话,还是看一下它的源代码,就抽一个Append吧,从下面这个截图中看出来几个有意思的地方。
<1> 原来StringBuilder里面维护的是一个m_ChunkChars的字符数组。
<2> 如果当前的字符串的length<2,会直接给chunkchars数组复制,length>2的时候看到的是刚才string类中经典的wstrcpy用法,而
这个时候ptr指向的是chunkChars[chunkLength]的首地址,而不像string中申请新的内存空间,所以从这里看,比string大大的节省
了内存空间。

好了,具体他们的性能比较我也不说了,大家看着他们的原理凑合着用吧,简单的看看也只能看到这了,再看就漏点了。
简单看看这两个类 String和StringBuilder的更多相关文章
- Reader与InputStream两个类中的read()的区别
InputStream类的read()方法是从流里面取出一个字节,他的函数原型是 int read(); ,Reader类的read()方法则是从流里面取出一个字符(一个char),他的函数原型也是 ...
- C#基础知识系列三(类和结构体、String和StringBuilder、equals和==)
前言 这一节主要来了解一下类和结构体之间的异同点.以及针对String和StringBuilder的用法.equals和==,其实可以看出很多地方都用到了上一节的值类型和引用类型.堆栈和装箱拆箱操作吧 ...
- 深入理解Java常用类----String
Java中字符串的操作可谓是最常见的操作了,String这个类它封装了有关字符串操作的大部分方法,从构建一个字符串对象到对字符串的各种操作都封装在该类中,本篇我们通过阅读String类的源码 ...
- 通过反射实现Microsoft Visual Studio International Pack 1.0 SR1里面的两个类
这两天打算实现拼音和简繁转换的方法, 发现Microsoft Visual Studio International Pack 1.0 SR1 提供了 . 下载地址 但是基于某些原因, 一来下载 ...
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
- 关于String和StringBuilder、StringBuffer的一个简单性能测试
String a=String b + String c + String d 这种代码在程序里应该随处可见,一部分人不知道这段代码的缺陷在哪,另一部分人知道这样写不好,但是太顺手了下意识就写了. 在 ...
- 【转】Unity3D 场景切换与持久化简单数据储存(PlayerPrefs类)
本篇文章主要介绍了"Unity3D 场景切换与持久化简单数据储存(PlayerPrefs类)",主要涉及到Unity3D 场景切换与持久化简单数据储存(PlayerPrefs类)方 ...
- 使用redis-py的两个类Redis和StrictRedis时遇到的坑
使用redis-py的两个类Redis和StrictRedis时遇到的坑 前言: 今天产品经理说,有几个队列排序的功能不能用了.对比了下以前的代码查到了一个原因,这个比较的坑,总结起来也是自己没好好看 ...
- 手写一个HTTP框架:两个类实现基本的IoC功能
jsoncat: 仿 Spring Boot 但不同于 Spring Boot 的一个轻量级的 HTTP 框架 国庆节的时候,我就已经把 jsoncat 的 IoC 功能给写了,具体可以看这篇文章&l ...
随机推荐
- .Net 高效开发之不可错过的实用工具(转)
.Net 高效开发之不可错过的实用工具(转) 本文摘自: http://www.cnblogs.com/powertoolsteam/p/5240908.html#3372237 Visual Stu ...
- jquery 删除cookie失效的解决方法
最近在做网站退出功能的时候出现删除Cookie 的时候总是失效. 1.使用$.cookie("name",""); 结果出来是生成了一个新的空值的cookie ...
- cookies
Cookie[] cookies=request.getCookies(); for(Cookie c:cookies) out.println(c.getValue()+" ") ...
- objective-c NSMutableAttributedString
NSMutableAttributedString 是一个很强悍的富文本处理字符串,可以方便的实现一个字符串中某个字符的样式处理.我把我下面代码实现的功能步骤说一下:首先拼接两个字符串,然后给前前半部 ...
- 2015暑假多校联合---Expression(区间DP)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5396 Problem Description Teacher Mai has n numb ...
- Java经典实例:进阶版堆栈实现,支持任何对象类型
支持任何对象类型,有更多的错误检查. package Stack; /** * Created by Frank */ public class MyStack<T> implements ...
- lodash常用方法1--查询
1.find var _ = require('lodash'); var user1 = { name: 'zhangsan', height: 180, weight: 120 }; var us ...
- ADO.NET(数据访问技术)
简单的说,C#已经内置了一些类,我们可以利用这些类来访问数据库.在这里,我们假设读者已经熟悉SqlServer数据库或者其它数据库(我以后也会补上相关内容).我们如何来实现这项技术呢?大致可以分为三个 ...
- 【追寻javascript高手之路04】理解prototype
前言 中午时候我去药店称了下体重,好家伙!我减肥成功了,足足比上个月瘦了10斤!于是想减肥就去郑州吧... 然后回来迷迷糊糊睡了一会,居然想起了周三的面试,有点小遗憾有点小触动. 这次回成都后,还没有 ...
- Bootstrap transition.js 插件详解
Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就是为了判断当前使用的浏览器是否支持 CSS 过渡.下面先来简单 ...