码迷,mamicode.com
首页 > 其他好文 > 详细

三大类库(一)之字符串性能分析

时间:2016-07-08 23:20:29      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

一、分析

String类字符串追加

  当我们对字符串进行拼接时,String:是对象不是原始类型.为不可变对象,一旦被创建,就不能修改它的值.对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.String 是sealed 类,即不能被继承.

    string是String类的别名,引用类型,且该类型是只读的,不可修改,当你修改字符串内容时,实际上是创建了另一个新的字符串并将引用指向了它,你可以参考String类型的构造函数说明,就明白错在哪里了。第一条只是创建了一个String类型的数组,并未对其初始化,如果你对该数组中的任一成员使用第二条的方法进行初始化,一样会报错。

     str += "a";等效于:str = new StringBuffer(str).append("a").toString(); 虽然编译器对字符串加号做了优化,它会用StringBuffer的append方法进行追加。再是通过toString方法转换成String字符串的。 它与纯粹的append方法是不同的 

一是每次都要创建一个StringBuilder对象 

二是每次执行完毕都要调用toString方法将其转换为字符串 

  因此,字符串类型的字符追加有可能会消耗大量的时间,因为每次追加完成之后都要return返回一个新的字符串,每次的操作都会一个新的String对象,这就是直接使用速度慢下来的原因。 

StringBuffer的字符串追加

 

     StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象,它只能通过构造函数来建立,StringBuffer sb = new StringBuffer();它不能直接对其进行赋值操作,sb = "I Hava a Dream";//错误,对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法.sb.append("当然的");

StringBuilder
-> 字符串不可变,长期拼接字符串性能较低
-> Stringbuilder
Append(string);
AppendLine(string);
AppendFormat("{0}{1}{2}{3}", 1, "23", "ab", true);
ToString();

     所以它必须通过追加的方式进行赋值。它的内部实现代码如下:

 1 public AbstractStringBuilder append(String str){ 
 2     //如果是null值,则把null作为字符串处理 
 3     if(str == null)str = "null"; 
 4  
 5     int len = str.length(); 
 6     //字符串的长度为0,则返回自身 
 7     if(len == 0)return this; 
 8  
 9     int newCount = count + len; 
10     //追加后的字符串组长度是否超过当前值 
11     if(newCount > value.length) 
12         expandCapacity(newCount);//加长,并作数组拷贝 
13     //字符串复制到目标数组 
14     str.getChars(0, len, value, count); 
15     count = newCount; 
16  
17     return this; 
18 } 

在StringBuffer中进行追加时不需要建立新的对象,开辟新的空间,它始终是一个对象,而String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.
这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的。

二、场景模拟

      我们使用Stopwatch类分别对这两种情况进行模拟计时,在C#中有一个秒表类:stopwatch,用这个类可以方便的测试一下代码运行时间。

 1 Stopwatch sp=new Stopwatch();
 2 sp.start();
 3 string s="";
 4 for(int i=0;i<100000;i++)
 5 {
 6         s+=i.toString();
 7 }
 8 sp.Stop();
 9 Console.WriteLine(sp.Elapsed);
10 Console.ReadKey();

结果表明:时间花了30多秒 

而对于StringBuilder:

 1 Stopwatch sp=new Stopwatch();
 2  sp.start();
 3  StringBuilder sb=new StringBuilder();
 4  for(int i=0;i<100000;i++)
 5  {
 6          s+=sb.Append(i.toString());
 7  }
 8  sp.Stop();
 9 Console.WriteLine(sp.Elapsed);
10  Console.ReadKey();

结果表明:时间花了0.几秒,相差了两个数量级

 

三、结论

当我们的系统性能不临界的时候,string类型的简答追加比较接地气,符合人们通常的写代码的习惯,而当系统性能临界,我们要进行数量级比较大的循环,我们就应该使用StringBuilder,提高我们的代码优化。

 

 

三大类库(一)之字符串性能分析

标签:

原文地址:http://www.cnblogs.com/fuGuy/p/5654576.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!