`
dongliwei122
  • 浏览: 81443 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

这个循环太让人郁闷了

阅读更多
今天做了一个关于Webservice的测试,测试的目的是向服务器获取1W条用户信息(XML格式),本来打算做1W、5W、10W条的测试,但是在1W条的时候就卡住了。生成数据竟然用了将近半个小时,郁闷!大家帮看一下啊!
不过也好,也暴露了一些问题,比如:Webservice超时、海量数据(XML)的解析
package cn.com.javaeye;

import java.util.Date;

/**
 * <br>
 *文件名:Test.java<br>
 *@author dongliwei<br>
 *版本:<br>
 *描述:<br>
 *创建时间:Apr 2, 2009 6:16:34 PM<br>
 *文件描述:<br>
 *修改者:<br>
 *修改日期:<br>
 *修改描述:<br>
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		long begin = new Date().getTime();
		String xml = getXML(1);
		long end = new Date().getTime();
		System.out.println("生成数据共耗时:" + (end-begin) + "毫秒");
	}

	/**
	 * 获取用户
	 * @param count 单位:万
	 * @return
	 */
	public  static String getXML(int count){
		count = count*10000;
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			   +"<users>";
		for(int  i = 0 ; i < count;i++){
			xml += 	"<user>"
						+"<id>001</id>"
						+"<name>zhangsan</name>"
						+"<empno>086001</empno>"
						+"<password>123456</password>"
						+"<mail>zhangsan@sina.com</mail>"
						+"<mobile>13733027580</mobile>"
						+"<address>北京市海淀区</address>"
						+"<sex>男</sex>"
						+"<organise>012</organise>"
						+"<role>1,2,3</role>"
						+"<group>1,5</group>"
					+"</user>";
			//System.out.println("生成" + (i+1) + "条数据");
		}
		xml += "</users>";
		return xml;
	}
}

经metadmin的指点,使用StringBuffer,就是不一样啊,仅仅用了239毫秒,在此谢过了!下面是修改过的代码
package cn.com.javaeye;

import java.util.Date;

/**
 * <br>
 *文件名:Test.java<br>
 *@author dongliwei<br>
 *版本:<br>
 *描述:<br>
 *创建时间:Apr 2, 2009 6:16:34 PM<br>
 *文件描述:<br>
 *修改者:<br>
 *修改日期:<br>
 *修改描述:<br>
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		long begin = new Date().getTime();
		String xml = getXML(1);
		long end = new Date().getTime();
		System.out.println("生成数据共耗时:" + (end-begin) + "毫秒");
	}

	/**
	 * 获取用户
	 * @param count 单位:万
	 * @return
	 */
	public  static String getXML(int count){
		count = count*10000;
		StringBuffer xml = new StringBuffer();
		
		xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		xml.append("<users>");
		for(int  i = 0 ; i < count;i++){
			xml.append("<user>");
			xml.append("<id>001</id>");
			xml.append("<name>zhangsan</name>");
			xml.append("<empno>086001</empno>");
			xml.append("<password>123456</password>");
			xml.append("<mail>zhangsan@sina.com</mail>");
			xml.append("<mobile>13733027580</mobile>");
			xml.append("<address>北京市海淀区</address>");
			xml.append("<sex>男</sex>");
			xml.append("<organise>012</organise>");
			xml.append("<role>1,2,3</role>");
			xml.append("<group>1,5</group>");
			xml.append("</user>");
			System.out.println("生成" + (i+1) + "条数据");
		}
		xml.append("</users>");
		return xml.toString();
	}
}
分享到:
评论
15 楼 night_stalker 2009-04-02  
RednaxelaFX 写道

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


似乎,异步操作的速度也在同步操作的百倍量级?……
14 楼 night_stalker 2009-04-02  
whaosoft 写道
+= 费内存吗??

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

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

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

StringBuffer费内存多一点。但是多次拼接的情况下速度快很多。
13 楼 leadyu 2009-04-02  
引用
其实测试用的这部分代码只是坏在+=那里而已。要知道Java里相邻的两个字符串字面量如果是用+来连接的话,编译结束后就变成一个字符串常量了。例如
Java代码
"a" + "b" 

"a" + "b"

Java代码
"ab" 

"ab"
等价。

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


LZ可以试试:

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

xml +=a;


搞不好比StringBuffer 还快?



12 楼 RednaxelaFX 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的代码。
11 楼 whaosoft 2009-04-02  
+= 费内存吗??
10 楼 night_stalker 2009-04-02  
metadmin 写道
<user>...</user>  这在编译的时候会被优化成一个String了,不会使用+算法。
而是xml+= 这个算法,进行了1w次加算法。
所以楼主后来改用了StringBuffer。


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

RednaxelaFX 的方法是最好的,速度比一堆 append 快,看起来也舒服。
9 楼 metadmin 2009-04-02  
<user>...</user>  这在编译的时候会被优化成一个String了,不会使用+算法。
而是xml+= 这个算法,进行了1w次加算法。

所以楼主后来改用了StringBuffer。
8 楼 kimmking 2009-04-02  
RednaxelaFX 写道
dongliwei122 写道
xml += 	"<user>"
      +"<id>001</id>"
      +"<name>zhangsan</name>"
      +"<empno>086001</empno>"
      +"<password>123456</password>"
      +"<mail>zhangsan@sina.com</mail>"
      +"<mobile>13733027580</mobile>"
      +"<address>北京市海淀区</address>"
      +"<sex>男</sex>"
      +"<organise>012</organise>"
      +"<role>1,2,3</role>"
      +"<group>1,5</group>"
    +"</user>";

其实测试用的这部分代码只是坏在+=那里而已。要知道Java里相邻的两个字符串字面量如果是用+来连接的话,编译结束后就变成一个字符串常量了。例如
"a" + "b"


"ab"

等价。

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

这个循环说:这个程序员太让我郁闷了。
7 楼 RednaxelaFX 2009-04-02  
dongliwei122 写道
xml += 	"<user>"
      +"<id>001</id>"
      +"<name>zhangsan</name>"
      +"<empno>086001</empno>"
      +"<password>123456</password>"
      +"<mail>zhangsan@sina.com</mail>"
      +"<mobile>13733027580</mobile>"
      +"<address>北京市海淀区</address>"
      +"<sex>男</sex>"
      +"<organise>012</organise>"
      +"<role>1,2,3</role>"
      +"<group>1,5</group>"
    +"</user>";

其实测试用的这部分代码只是坏在+=那里而已。要知道Java里相邻的两个字符串字面量如果是用+来连接的话,编译结束后就变成一个字符串常量了。例如
"a" + "b"


"ab"

等价。

另外,同上,Java 5或以上的话请用StringBuilder。
6 楼 kevinhlj 2009-04-02  
有人已经说了,

webservice要避免大数据量应用,这才是正道,

你再优化也是有一个打包过程的,
5 楼 longrui 2009-04-02  
改成StringBuilder再试试,如果你的JDK版本是5.0以上的话...
4 楼 yangyi 2009-04-02  
放在循环里,编译器能优化吗
3 楼 fjlyxx 2009-04-02  
Webservice 1W5W LZ你太NB了 建议你分包或者限制条数吧
2 楼 dongliwei122 2009-04-02  
metadmin 写道
这么多字符串拼接,使用StringBuffer


-----------------------
权限管理圈子欢迎您加入:
http://accessmanager.group.iteye.com/

谢谢哈,我咋忘了这个啊。呵呵!万分感激!
1 楼 metadmin 2009-04-02  
这么多字符串拼接,使用StringBuffer

相关推荐

    脚本解析器 脚本引擎

    c 语言模式脚本解析器,脚本执行不是其目的。其作用是对PE文件进行编辑。暂且不论。 现在仅支持 if关键字... 今天测试循环 发现效率实在令人郁闷。先不管了(感觉递归引起的) 代码照样没释放内存,存在内存泄露问题。

    脚本引擎 脚本解析器

    author:ListenWind ...c 语言模式脚本解析器,脚本执行不是其目的。其作用是对PE文件进行编辑。...今天测试循环 发现效率实在令人郁闷。先不管了(感觉递归引起的) 代码照样没释放内存,存在内存泄露问题。

    VS中C++代码折叠

    这不免让人郁闷。  VS对C/C++语言,默认仅折叠预处理命令(#include, #pragma等)、类、函数等。如果某个函数特别长,大大超出了屏幕范围,特别是多重循环时,很难确定哪个循环在哪终止,十分不便。  VS虽然没...

    使用distinct在mysql中查询多条不重复记录值的解决办法

    其原因是distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,我只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。...

    c语言程序设计实践报告.docx

    其间开心过、郁闷过、无奈过、彷徨过……随着实验的胜利成功与实验报告的胜利完成,有点微微的自豪感使人难忘。感谢高克宁老师的高标准、严要求,感谢实验课上小老师们的耐心指点,也感谢我在实验中经历过的点点滴滴...

    如何编写批处理文件批处理文件批处理文件

    @format X: /q/u/autoset (format 这个命令是不可以使用/y这个参数的,可喜的是微软留了个autoset这个参数给我们,效果和/y是一样的。) 3.Goto 命令 指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。 ...

    网摘精灵软件包1.5

    花费很大心血做了个网站,却没有什么人知道,网站价值不能体现出来,是不是很郁闷?好东西不被人了解和认可,是不是很沮丧? 酒香也怕巷子深。网站做出来了还不够,还要告诉大家,网络世界中有这么个网站。 网站...

    一个友好的.改善的 Object.prototype.toString的实现

    然而,对于我们最常用的 Object 对象,每次使用 toString 方法都会打印出 “[object Object]” 的结果,让人感到非常郁闷。 为了解决这个问题,我们可以实现一个友好的函数,打印 Object 的各成员,支持嵌套输出,...

    vb入门指南

    《VB入门指南》是一份专为初学者设计的编程学习资料,主要针对Visual Basic(VB)这一编程语言。...尽管电子版文档的原出处不明,但尊重原出版人的权益,合理使用这份资源,将对个人的编程学习之路大有裨益。

Global site tag (gtag.js) - Google Analytics