asp.net C# string 与 stringBuffer

作者:袖梨 2022-06-25

asp教程.net c# string 与 stringbuffer

关键点
    1). 简单的认为 .append() 效率好于 "+" 是错误的!
    2). 不要使用 new 创建 string
    3). 注意 .intern() 的使用
    4). 在编译期能够确定字符串值的情况下,使用"+"效率最高
    5). 避免使用 "+=" 来构造字符串
    6). 在声明stringbuffer对象的时候,指定合适的capacity,不要使用默认值


首先我们必须清楚的一点是string类是final类型的,因此你不可以继承这个类、不能修改这个类。我们使用string的时候非常简单,通常都是string s = "hello",但是java api中同时提供了一个构造函数为string(string s),因此你也可以这样使用string s = new string("hello"),对于后面这样初始化一个string的方式是不推荐的,因为new操作符意味着将会在heap上生成一个新的对象,如果这样的操作发生在一个循环中,那么代价是惨重的。比如
for(int i = 0;i<1000;i++)
{
    string s = new string("hello");
}
    这将会创建1000个string类型的对象,由于string类是final的,因此这样的操作事实上是每次都生成了一个新的string对象的。如果你使用string s = "hello";那么就可以实现复用了,为什么可以复用呢,下面会有解释:
string s = "hello";
jvm先根据内容"hello"查找对象,如果没有找到,则在heap上创建新对象,并将其赋予s1,否则使用已经存在的对象
string s = new string("hello");
jvm直接在heap上创建新的对象,所以在heap中会出现内容相同,地址不同的string对象
stringbuffer是产生一块内存空间,进行相干的增删改操作都在这块可扩展的内存上来操作,所以它对内存空间的消耗是有优化的,特别是在循环中
效率:string 与 stringbuffer
    情景1:
    (1) string result = "hello" + " world";
    (2) stringbuffer result = new string().append("hello").append(" world");
        (1) 的效率好于 (2),不要奇怪,这是因为jvm会做如下处理
        编译前   string result = "hello" + " world";
        编译后   string result = "hello world";

 
    情景2:
    (1) public string getstring(string s1, string s2) {
            return s1 + s2;
        }
    (2) public string getstring(string s1, string s2) {
            return new stringbuffer().append(s1).append(s2);
        }
        (1) 的效率与 (2) 一样,这是因为jvm会做如下处理
        编译前   return s1 + s2;
        编译后   return new stringbuffer().append(s1).append(s2);

    情景3:
    (1) string s = "s1";
              s += "s2";
              s += "s3";
    (2) stringbuffer s = new stringbuffer().append("s1").append("s2").append("s3");
        (2) 的效率好于(1),因为string是不可变对象,每次"+="操作都会造成构造新的string对象

    情景4:
    (1) stringbuffer s = new stringbuffer();
        for (int i = 0; i < 50000; i ++) {
            s.append("hello");
        }
    (2) stringbuffer s = new stringbuffer(250000);
        for (int i = 0; i < 50000; i ++) {
            s.append("hello");
        }
      
        (2) 的效率好于 (1),因为stringbuffer内部实现是char数组,默认初始化长度为16,每当字符串长度大于char
        数组长度的时候,jvm会构造更大的新数组,并将原先的数组内容复制到新数组,(2)避免了复制数组的开销       
  

 

相关文章

精彩推荐