论坛首页 入门技术论坛

这个循环太让人郁闷了

浏览 12407 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-04-02   最后修改:2009-04-02
metadmin 写道
<user>...</user>  这在编译的时候会被优化成一个String了,不会使用+算法。
而是xml+= 这个算法,进行了1w次加算法。
所以楼主后来改用了StringBuffer。


关键是StringBuffer使分配内存的次数从 n 变成了 log n 。
拼接什么的,耗时间在分配内存的 1/100 量级。

RednaxelaFX 的方法是最好的,速度比一堆 append 快,看起来也舒服。
0 请登录后投票
   发表时间:2009-04-02  
+= 费内存吗??
0 请登录后投票
   发表时间:2009-04-02   最后修改:2009-04-02
night_stalker 写道
metadmin 写道
<user>...</user>  这在编译的时候会被优化成一个String了,不会使用+算法。
而是xml+= 这个算法,进行了1w次加算法。
所以楼主后来改用了StringBuffer。


关键是StringBuffer使分配内存的次数从 n 变成了 log n 。
拼接什么的,耗时间在分配内存的 1/100 量级。

RednaxelaFX 的方法是最好的,速度比一堆 append 快,看起来也舒服。

Java 5开始有StringBuilder来替代StringBuffer,而实际上从Java 5开始它们的内部实现几乎是一样的,不同之处在于StringBuffer的操作都是同步的,而StringBuilder的都是不同步;它们都继承自AbstractStringBuilder,具体实现其实都在这个基类里……
所以单线程条件下没什么理由非要用StringBuffer而不用StringBuilder。虽然Sun Hotspot从Java 6开始有所谓的bias locking,但总还是得检查那么一下,对单线程程序而言还是有无谓的开销。

whaosoft 写道
+= 费内存吗??

费。不过也要看你怎么看,认为多少才是“费”。
Java里两个相邻的字符串字面量如果用+来连接,编译器能帮忙把字面量合成在一起。但如果是String变量就没有此等待遇,基本上每碰到一个+就会变成一组new StringBuilder -> append这样的过程;换言之会创建许多生命很短的小对象。+=是+的复合赋值运算符,其左手边的必须是左值,所以参与运算的左右两侧就不可能都是字面量,进而不可能由编译器做合成,而只能生成new StringBuilder + append的代码。
2 请登录后投票
   发表时间:2009-04-02  
引用
其实测试用的这部分代码只是坏在+=那里而已。要知道Java里相邻的两个字符串字面量如果是用+来连接的话,编译结束后就变成一个字符串常量了。例如
Java代码
"a" + "b" 

"a" + "b"

Java代码
"ab" 

"ab"
等价。

另外,同上,Java 5或以上的话请用StringBuilder。


LZ可以试试:

String a =".."+".." +...; //都是常量

xml +=a;


搞不好比StringBuffer 还快?



0 请登录后投票
   发表时间:2009-04-02   最后修改:2009-04-02
whaosoft 写道
+= 费内存吗??

设n为拼接操作的次数,alloc_time为分配内存的时间

String:
每次都丢弃原来的内存,新分配一块内存给结果。
时间复杂度 n*alloc_time

StringBuffer:
占用的空间大于字符串的长度,当字符串充满这块内存时,重新分配一块两倍大的内存给它。
时间复杂度 (log n)*alloc_time

StringBuffer费内存多一点。但是多次拼接的情况下速度快很多。
0 请登录后投票
   发表时间:2009-04-02  
RednaxelaFX 写道

Java 5开始有StringBuilder来替代StringBuffer,而实际上从Java 5开始它们的内部实现几乎是一样的,不同之处在于StringBuffer的操作都是同步的,而StringBuilder的都是不同步;它们都继承自AbstractStringBuilder,具体实现其实都在这个基类里……
所以单线程条件下没什么理由非要用StringBuffer而不用StringBuilder。虽然Sun Hotspot从Java 6开始有所谓的bias locking,但总还是得检查那么一下,对单线程程序而言还是有无谓的开销。


似乎,异步操作的速度也在同步操作的百倍量级?……
0 请登录后投票
   发表时间:2009-04-02  
night_stalker 写道
StringBuffer:
占用的空间大于字符串的长度,当字符串充满这块内存时,重新分配一块两倍大的内存给它。

嗯,具体是(length + 1) * 2
0 请登录后投票
   发表时间:2009-04-03  
RednaxelaFX 写道

嗯,具体是(length + 1) * 2


弱问加 1 的意义何在……
0 请登录后投票
   发表时间:2009-04-03  
night_stalker 写道
弱问加 1 的意义何在……

印象中在哪里看到过这个设计理由的……嗯我想不起来了。但Sun的JDK里就是这么实现的 =v=
0 请登录后投票
   发表时间:2009-04-03  
1 好好看看java基础,否则会害死将来的人.
2 如果不要求线程同步,请用stringBuilder,比buffer快
3 代码很整齐,赞一下
4 万单位的数据,成功率太低,分包吧
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics