为什么连接字符串一定要用StringBuilder(介绍CLR Profiler)

简介:

当然啦,很多人开始学习C#的时候,就已经听到过来自多方的警告,连接字符串的时候一定要用StringBuilder,不要使用String直接连接的方式,而且也都知道其中的原因,例如什么因为String是一个固定的变量,不能更改,每一次String连接的操作实际上都是创建了一个新的String实例。可能很少有人知道具体的数据是什么,因为我们不能尽信书本上说的,一定要有一些实验数据才可以。

 

让我们看下面的两份代码,一份是使用String来进行字符串连接操作的:

using System;

 

public class StringTest

{

    public static void Main()

    {

        string str = "";

 

 

        DateTime begin = DateTime.Now;

        for (int i = 0; i < 100000; ++i)

            str += i;

        DateTime end = DateTime.Now;

 

        Console.WriteLine(begin - end);

    }

}

 

另外一份是使用StringBuilder来进行字符串连接操作的。

using System;

using System.Text;

 

public class StringBuilderTest

{

    public static void Main()

    {

        StringBuilder str = new StringBuilder();

 

        DateTime begin = DateTime.Now;

        for (int i = 0; i < 100000; ++i)

            str.Append(i);

        DateTime end = DateTime.Now;

 

        Console.WriteLine(end - begin);

    }

}

 

当然啦,结果是大家都已经知道的,就是String版本的程序的速度要比StringBuilder的速度慢很多。

 

为什么String版本的程序会比StringBuilder程序慢那么多呢已经不是简简单单的倍数级别的差别了。这里我介绍一个工具—CLR Profiler,程序员可以使用这个工具了解到自己的程序到底创建了多少个对象,GC发生了多少次,以及各个函数之间的调用关系是怎样的。

 

1.         下载CLR Profiler以后,启动它,点击“Start Application”按钮。

2.         选择我们要剖析的.NET程序,实际上CLR Profiler还可以剖析我们的ASP.NET网站程序。

3.         等待程序执行完毕,CLR Profiler就会详细地给你列出整个程序运行过程当中发生的问题了。

 

例如下图(这个图比上面的示例程序的循环次数少,只有原来的十分之一,因为示例程序生成的日志文件太大,我机器的内存被消耗光了),我们可以看到系统分配了379,458,639也就是将近400M的内存,而最后Final Heap内存的大小只有355,527—就是最后我们的连接起来的最终字符串的大小,而整个循环过程当中,有340 + 19次的GC操作,我们知道GC操作是非常耗费时间的一个操作,这也就是为什么我们看到String版本的程序运行速度如此之慢。

 

点击上图里面的“Allocation Graph”之后,我们会发现所有的内存分配操作都是为System.String执行的,在内存当中,String的实例有20231个,占去被分配内存空间的99.96%



本文转自 donjuan 博客园博客,原文链接:http://www.cnblogs.com/killmyday/archive/2009/03/10/1407432.html   ,如需转载请自行联系原作者

相关文章
|
存储 开发框架 搜索推荐
【深入理解CLR 二】CLR的执行模型(上)
【深入理解CLR 二】CLR的执行模型(上)
222 0
【深入理解CLR 二】CLR的执行模型(上)
|
开发框架 人工智能 自然语言处理
【深入理解CLR 二】CLR的执行模型(下)
【深入理解CLR 二】CLR的执行模型(下)
126 0
|
Unix
C代码中__LINE__输出时与代码行号不同的解决办法
C代码中__LINE__输出时与代码行号不同的解决办法
109 0
|
SQL Java 数据库连接
第一个JDBC程序
第一个JDBC程序
|
SQL 存储 程序员
C#连接数据库之Connection、Command、DataReader用法总结
C#连接数据库之Connection、Command、DataReader用法总结
412 0
C#连接数据库之Connection、Command、DataReader用法总结
|
缓存 开发框架 运维
C#好代码学习笔记(1):文件操作、 读取文件、Debug/Trace类、Conditional条件编译、CLS
C#好代码学习笔记(1):文件操作、 读取文件、Debug/Trace类、Conditional条件编译、CLS
253 0
|
编译器 Linux Windows
使用 include<con> “杀死“ 编译器
使用 include<con> “杀死“ 编译器的尝试和原理
|
.NET C# C++
关于CLR、CIL、CTS、CLS、CLI、BCL和FCL 的区分与总结
关于CLR、CIL、CTS、CLS、CLI、BCL和FCL 的区分与总结 如果要想深入学习.NET平台,那么标题中的这些关键字对你来说并不陌生,这些名词构成了.NET庞大的生态系统,为了宏观认识.NET平台,学些.NET架构体系,针对一些常用常用名词的理解是很有必要的,未必强行记忆,但至少要知道它们的含义。
2283 0
|
关系型数据库 PostgreSQL 索引
PostgreSQL cheat functions - (内存上下文\planner内容\memory context等常用函数)
标签 PostgreSQL , memory context , plan , pid signal , ... 背景 https://github.com/MasaoFujii/pg_cheat_funcs Fujii Masao MasaoFujii PostgreSQL comm...
1336 0