在重复对字符串进行修改操作下,不是StringBulider比String更有优势吗,怎么会我用以下的代码利用运行时间差进行测试,得到的却是相反的结果呢??难道占用内存与运行时间是熊掌跟鱼的关系!!  为什么??        
                      几组结果:   StringBuilder            String           1)           0.2203168                 0.1301872           2)           0.2303312                 0.1301872
          
           3)           0.2203168                 0.1402016           StringBuilder b = new StringBuilder("hello"); 
            DateTime T3 = System.DateTime.Now;
            for (int i = 0; i < 20; i++)
            {
                b.Append(b);
            }
            TimeSpan Ts2 = System.DateTime.Now - T3;
            Console.WriteLine(Ts2.TotalSeconds.ToString());
            string a = "hello";
            DateTime T1 = System.DateTime.Now;
            for (int i = 0; i < 20; i++)
            {
                a += a;
            }
            TimeSpan Ts1 = System.DateTime.Now - T1;
            Console.WriteLine(Ts1.TotalSeconds.ToString());

解决方案 »

  1.   

    1、你的20这个数值太小了
    2、b.Append(b);//你这里b是StringBuilder类型的,所以会有一个ToString的调用,显然在循环中这是很影响效率的。
      

  2.   

    hehe 
    这样 你这样测下
    1 StringBuilder b = new StringBuilder("hello"); //这句刨除在测试之外,再对比下结果
    2.StringBuilder b=new StringBuilder(); b.Append("hello");//改成这样再测测
    3.b.Append("hello");  a+="hello";//这样再测测
    //123 可混合测试
      

  3.   

    在我的机器上
    0.09375
    0.0625把Append的参数改为字符串"hello"
    则是
    0
    0.0625
      

  4.   

    显然是Append参数类型使用StringBuilder所致楼主的机器似乎没有我的快,呵呵~
      

  5.   

    你把程序改成这样:
    StringBuilder b = new StringBuilder("hello"); 
    DateTime T3 = System.DateTime.Now;
    for (int i = 0; i < 20000; i++)
    {
    b.Append("0");
    }
    TimeSpan Ts2 = System.DateTime.Now - T3;
    richTextBox1.Text = Ts2.TotalSeconds.ToString();
    string a = "hello";
    DateTime T1 = System.DateTime.Now;
    for (int i = 0; i < 20000; i++)
    {
    a += "0";
    }
    TimeSpan Ts1 = System.DateTime.Now - T1;
    richTextBox1.Text += "\n" +  Ts1.TotalSeconds.ToString();
    执行结果是
    0
    0.296875你的程序是把自身在复制,主要是在测试机器的性能,而不是你想要的目的
      

  6.   

    i agree with viena(维也纳nn). i do the same.because the stringbuilder is a reference type, it will cost more time to convert to string while use the snippet "b.Append(b)".
      

  7.   

    改成"hello"两个都是0
    不过这与楼主的要求不符了
      

  8.   

    谢谢Ivony() ( 两星(中级))的解析,第一种情况,我也不是没考虑过,只是仅将20改为50,就提示虚拟内存不够了(2根256RAM了,应该不会是配置问题吧),无解ing;
    第二种情况,这个解析倒是赞同;不知还有其他的解析没。。另外,还想问下,StringBulider相对于string来说,优势只体现在占用内存少,以及修改频繁时(ps:起码>20 ^_^),还有处理时间少的好处呢
      

  9.   

    楼主的要求是自身复制到自身
    效率最高的方法应该是用char数组
    用Buffer.BlockCopy复制或者用Unsafe代码,用int型指针
      

  10.   

    程序应改为这样:      string s = "hello";      Stopwatch watch = new Stopwatch();
          StringBuilder b = new StringBuilder( s );
          watch.Start();
          for ( int i = 0; i < 2000; i++ )
          {
            b.Append( s );//这里避免ToString损耗
          }
          watch.Stop();
          Console.WriteLine( watch.ElapsedMilliseconds );      string a = s;
          watch.Start();
          for ( int i = 0; i < 2000; i++ )
          {
            a += s;//这里不能用a+=a,否则会造成19+18+...+1个hello相加。
          }
          watch.Stop();
          Console.WriteLine( watch.ElapsedMilliseconds );      Console.Read();
    在循环200次以下根本没法比较结果,在循环2000次开始有差异,StringBuilder所耗费的时间始终是0,而+=耗费的时间随着循环的次数急剧上升。
      

  11.   

    感觉StringBulider这个词不确切,不如Java里的StringBuffer贴切
    虽然两个都可以简称SB,但是含义不一样了
    我感觉StringBulider就是个字符串缓冲区~
      

  12.   

    谢谢Ivony() ( 两星(中级))的解析,第一种情况,我也不是没考虑过,只是仅将20改为50,就提示虚拟内存不够了(2根256RAM了,应该不会是配置问题吧),无解ing;那是因为你的程序会造成2的50次方(刚刚算错了)个hello,2的8次方就是1K,16次方就是1M,24次方就是1G了,想想2的50次方个hello是多少?
      

  13.   

    内存不够是你算法的问题
     b.Append(b)是2的50次方,你可以计算一下这个字节有多大,再加上基数是5个字节,当然内存就不够了
      

  14.   

    感觉StringBulider这个词不确切,不如Java里的StringBuffer贴切
    虽然两个都可以简称SB,但是含义不一样了
    我感觉StringBulider就是个字符串缓冲区~
    ================================================================比较一下Builder系的类和Buffer系的类:StringBuilder、UriBuilder
    BufferedStream
    StringBuilder用处更多的还是在于构建(Builder),至于缓存(Buffer)只是构建时采取的提高效率的方法,这样的命名是合理的。
      

  15.   

    谢谢cancerser 、viena(维也纳nn),你们给的答案正是我要的结果,我写的代码就是为了测试下对StringBuilder比string进行修改操作时,有什么好处。hoho  顺便说下我的座机是SP2400+ 2根256RAM 是比较挫了。
      

  16.   

    看看MSDN里怎么说吧String 对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。通过用一个重载的构造函数方法初始化变量,可以创建 StringBuilder 类的新实例,正如下面的示例中所阐释的那样。设置容量和长度
    虽然 StringBuilder 对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前 StringBuilder 对象容纳的字符串长度混淆在一起。例如,可以创建 StringBuilder 类的带有字符串“Hello”(长度为 5)的一个新实例,同时可以指定该对象的最大容量为 25。当修改 StringBuilder 
      

  17.   

    SP2400+ 2根256RAM
    我用赛扬1.7+256DDR+15球面开发了整个大学...
      

  18.   

    这个.......我只想说2的10次方是1K,2的20次方是1M,2的30次方是1G.
    为什么看见楼上有出来8的?
      

  19.   

    从面向对象的角度分析string每做一次加长的链接,相当于声明了一个新的对象而StringBulider仅是修改一个对象的属性值所以StringBulider对于大量数据链接的情况下,决定是优势的
      

  20.   

    说明:对字符串进行连接操作时,尽量使用StringBuilder类的Append方法,相对于“+”符号来说,使用StringBuilder类的Append方法看起来显得更易理解,更重要的是,使用StringBuilder性能要高很多。因为StringBuilder会预先分配一定大小的内存来放置字符串内容。以后append的时候,尽可能的在当前内存块内操作。而String却是每次都重新new一个新对象
      

  21.   

    这个.......我只想说2的10次方是1K,2的20次方是1M,2的30次方是1G.
    为什么看见楼上有出来8的?
    ==================================================================是我计算错误……