锁定老帖子 主题:这个循环太让人郁闷了
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-02
最后修改:2009-04-02
metadmin 写道 <user>...</user> 这在编译的时候会被优化成一个String了,不会使用+算法。
而是xml+= 这个算法,进行了1w次加算法。 所以楼主后来改用了StringBuffer。 关键是StringBuffer使分配内存的次数从 n 变成了 log n 。 拼接什么的,耗时间在分配内存的 1/100 量级。 RednaxelaFX 的方法是最好的,速度比一堆 append 快,看起来也舒服。 |
|
返回顶楼 | |
发表时间:2009-04-02
+= 费内存吗??
|
|
返回顶楼 | |
发表时间: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的代码。 |
|
返回顶楼 | |
发表时间:2009-04-02
引用 其实测试用的这部分代码只是坏在+=那里而已。要知道Java里相邻的两个字符串字面量如果是用+来连接的话,编译结束后就变成一个字符串常量了。例如
Java代码 "a" + "b" "a" + "b" 与 Java代码 "ab" "ab" 等价。 另外,同上,Java 5或以上的话请用StringBuilder。 LZ可以试试: String a =".."+".." +...; //都是常量 xml +=a; 搞不好比StringBuffer 还快? |
|
返回顶楼 | |
发表时间:2009-04-02
最后修改:2009-04-02
whaosoft 写道 += 费内存吗??
设n为拼接操作的次数,alloc_time为分配内存的时间 String: 每次都丢弃原来的内存,新分配一块内存给结果。 时间复杂度 n*alloc_time StringBuffer: 占用的空间大于字符串的长度,当字符串充满这块内存时,重新分配一块两倍大的内存给它。 时间复杂度 (log n)*alloc_time StringBuffer费内存多一点。但是多次拼接的情况下速度快很多。 |
|
返回顶楼 | |
发表时间:2009-04-02
RednaxelaFX 写道 Java 5开始有StringBuilder来替代StringBuffer,而实际上从Java 5开始它们的内部实现几乎是一样的,不同之处在于StringBuffer的操作都是同步的,而StringBuilder的都是不同步;它们都继承自AbstractStringBuilder,具体实现其实都在这个基类里…… 所以单线程条件下没什么理由非要用StringBuffer而不用StringBuilder。虽然Sun Hotspot从Java 6开始有所谓的bias locking,但总还是得检查那么一下,对单线程程序而言还是有无谓的开销。 似乎,异步操作的速度也在同步操作的百倍量级?…… |
|
返回顶楼 | |
发表时间:2009-04-02
night_stalker 写道 StringBuffer:
占用的空间大于字符串的长度,当字符串充满这块内存时,重新分配一块两倍大的内存给它。 嗯,具体是(length + 1) * 2 |
|
返回顶楼 | |
发表时间:2009-04-03
RednaxelaFX 写道 嗯,具体是(length + 1) * 2 弱问加 1 的意义何在…… |
|
返回顶楼 | |
发表时间:2009-04-03
night_stalker 写道 弱问加 1 的意义何在……
印象中在哪里看到过这个设计理由的……嗯我想不起来了。但Sun的JDK里就是这么实现的 =v= |
|
返回顶楼 | |
发表时间:2009-04-03
1 好好看看java基础,否则会害死将来的人.
2 如果不要求线程同步,请用stringBuilder,比buffer快 3 代码很整齐,赞一下 4 万单位的数据,成功率太低,分包吧 |
|
返回顶楼 | |