简单看看这两个类 String和StringBuilder

  我记得以前在园子里面讨论这两个类的文章有很多很多,并且还拿出了很多的测试报告,在什么情况下,谁比谁快,在什么情况下,该用谁

不该用谁等等这些,我这里就不比较了,我就简单看看他们里面的内部实现,那就先看看String吧。

 

一:String类

  说到String类,资料上都说是存在于堆上的一个不可CURD的一个不可变的字符集,当然看到这句话之后就想要看看是不是这样的,然后就

好奇的写了以下代码。

class Program
    {
        static void Main(string[] args)
        {
            string s = "123";
        }
    }

 

从上面的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大大的节省

    了内存空间。

 

好了,具体他们的性能比较我也不说了,大家看着他们的原理凑合着用吧,简单的看看也只能看到这了,再看就漏点了。

时间: 2024-08-01 09:52:21

简单看看这两个类 String和StringBuilder的相关文章

一个简单安全的PHP验证码类、PHP验证码_php实例

一,验证码示例 二,php验证码类,secoder.class.php <?php /** * 安全验证码 * * 安全的验证码要:验证码文字扭曲.旋转,使用不同字体,添加干扰码 * * @author 流水孟春 <cmpan(at)qq.com> * @link http://labs.yulans.cn/YL_Security_Secoder * @link http://wiki.yulans.cn/docs/yl/security/secoder */ class YL_Secu

一个简单安全的PHP验证码类、PHP验证码

一,验证码示例 二,php验证码类,secoder.class.php <?php /** * 安全验证码 * * 安全的验证码要:验证码文字扭曲.旋转,使用不同字体,添加干扰码 * * @author 流水孟春 <cmpan(at)qq.com> * @link http://labs.yulans.cn/YL_Security_Secoder * @link http://wiki.yulans.cn/docs/yl/security/secoder */ class YL_Secu

类 String详细用法小结

所有已实现的接口: Serializable, CharSequence, Comparable<String> public final class String extends Objectimplements Serializable, Comparable<String>, CharSequence String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现. 字符串是常量:它们的值在创建之后不能更改.字符串缓

ASP.NET设计网络硬盘之两重要类

asp.net|设计|网络|硬盘 要进行"网络硬盘"功能设计,首先要熟悉.NET中处理文件和文件夹的操作.File类和Directory类是其中最主要的两个类.了解它们将对后面功能的实现提供很大的便利. System.IO.File类和System.IO.FileInfo类 在设计和实现"网络硬盘"的过程中,将大量地使用和文件系统操作相关的内容.故本节先对和文件系统相关的两个.NET类进行简要介绍. System.IO.File类和System.IO.FileInf

Android网络操作常用的两个类

Android SDK集成了Apache HttpClient模块.要注意的是,这里的Apache HttpClient模块是 HttpClient 4.0(org.apache.http.*),而不是常见的 Jakarta Commons HttpClient 3.x (org.apache.commons.httpclient.*). HttpClient常用 HttpGet和HttpPost这两个类,分别对应Get方式和Post方式. 无论是使用HttpGet,还是使用HttpPost,都

简单的PHP数据库处理类

最近在看后盾网的php视频,主要内容是相关制作一个博客系统,感觉还是很有收获. 简单的数据库处理类 下面是其中讲到的一个简单的数据库处理类,请见源码:     代码如下 复制代码   <?php     /**     * Created by JetBrains PhpStorm.     * User: YangLiu     * Date: 2013-7-12     * Time: 下午6:19     * Description:这是一个简单的数据库操作类,便于快速向数据库插入数据.删

ava 实例化-两个类,实例化问题,实例化报错

问题描述 两个类,实例化问题,实例化报错 public class Paixu { public static void main(String[] args) { // Paixu px=new Paixu(); MaoPaoSort mp=new MaoPaoSort();//上面这里就开始报错了:No enclosing instance of type Paixu is accessible. Must qualify the allocation with an enclosing i

C# Aop简单扫盲及ORM实体类属性拦截示例

先说下场景,C#中为什么要使用Aop,而我又是在哪里使用Aop? 本人只是想拦截实体类的Set的方法,然后在Set之前,调用一下其它方法,把值赋给另一个对象.   而我做的都是在实体类的基类里处理: 比如: public class OrmBase   让所有继承这个基类的实体类都具有Orm操作功能,再加上一个小小特殊的要求处理,属性Set时,需要对另一对象赋值.   如果说,我这样实现:在OrmBase中可以提供方法,让所有的子类的属性都这样操作:   public class Users:O

为什么java源文件中有两个类编译后只产生一个类文件

问题描述 classdemoA{publicstaticvoidmain(String[]args){demoad=newdemoa();d.getmoney();}voidgetmoney(){System.out.println("package123123123");}}classdemoa{voidgetmoney(){System.out.println("package1111");}}为什么java源文件中有两个类编译后只产生一个类文件demoA,且运