前几天性能测试的时候发现一个web 端cpu出现骤降的问题,一直没有找到原因,起初怀疑是tomcat的线程数有关,后来有怀疑是跟数据库的响应时间太长有关系,后来都一一排除了。
之所以此问题比较难以定位主要是因为通过现有的监控工具无法获知和分析tomcat内部各个线程的占用资源的情况。
上周装了一下jprofiler,然后又重新进行了一次压力测试,终于找到了问题的根源:)
主要的资源消耗点是:字符串的拼接上。代码中时使用”+“来进行字符串连接的。
(ps:jprofiler监控的粒度很细,但是由于其本身运行占用的资源消耗量也很大,因此在进行性能测时不能用其作为监控工具,在分析问题方面还是蛮有用的;jconsole是java自带的监控工具,其在远程监控应用程序时,不会对程序的性能造成影响,但由于其监控的粒度还是有些粗,因此tomcat内部的资源占用情况还是无法进行分析的)
JAVA中String ,StringBuffer,SrtingBuilder三个对象连接字符串的效率。
比较下究竟谁的效率高。因为我们经常都听有经验的人说,避免使用String通过“+”连接字符串,特
别是连接的次数很多的时候,一定要用StringBuffer,但究竟效率多高,速度多快,我也没有测试过,
所以我就动手测试下,顺便把测试结果跟大家一起分享,希望大家共同讨论此问题。
下边是我的测试代码,可直接运行:
public class TestStringConnection { //连接时间的设定 private final static int n = 20000; public static void main(String[] args){ TestStringConnection test = new TestStringConnection (); test.testStringTime(n); test.testStringBufferTime(n); test.testStringBuilderTime(n); // //连接10次 // test.testStringTime(10); // test.testStringBufferTime(10); // test.testStringBuilderTime(10); // // //连接100 // // test.testStringTime(100); // test.testStringBufferTime(100); // test.testStringBuilderTime(100); // // // // //连接1000 // // test.testStringTime(1000); // test.testStringBufferTime(1000); // test.testStringBuilderTime(1000); // // // //连接5000 // // test.testStringTime(5000); // test.testStringBufferTime(5000); // test.testStringBuilderTime(5000); // // // //连接10000 // // test.testStringTime(10000); // test.testStringBufferTime(10000); // test.testStringBuilderTime(10000); // // //连接20000 // // test.testStringTime(20000); // test.testStringBufferTime(20000); // test.testStringBuilderTime(20000); } /** *测试String连接字符串的时间 */ public void testStringTime(int n){ long start = System.currentTimeMillis(); String a = ""; for(int k=0;k<n;k++ ){ a += "_" + k; } long end = System.currentTimeMillis(); long time = end - start; System.out.println("//////////////////////连接"+n+"次" ); System.out.println("String time "+n +":"+ time); //System.out.println("String str:" + str); } /** *测试StringBuffer连接字符串的时间 */ public void testStringBufferTime(int n){ long start = System.currentTimeMillis(); StringBuffer b = new StringBuffer() ; for(int k=0;k<n;k++ ){ b.append( "_" + k ); } long end = System.currentTimeMillis(); long time = end - start; System.out.println("StringBuffer time "+n +":"+ time); //System.out.println("StringBuffer str:" + str); } /** *测试StringBuilder连接字符串的时间 */ public void testStringBuilderTime(int n){ long start = System.currentTimeMillis(); StringBuilder c = new StringBuilder() ; for(int k=0;k<n;k++ ){ c.append( "_" + k ); } long end = System.currentTimeMillis(); long time = end - start; System.out.println("StringBuilder time " +n +":"+ time); System.out.println("//////////////////////"); //System.out.println("StringBuffer str:" + str); } }
测试环境:eclipse
|
但是为什么String如此慢呢,分下如下简单片段 String result="";
result+="ok";
这段代码看上去好像没有什么问题,但是需要指出的是其性能很低,原因是java中的String
类不可变的(immutable),这段代码实际的工作过程会是如何的呢?通过使用javap工具我
们可以知道其实上面的代码在编译成字节码的时候等同的源代码是: String result="";
原文地址:http://hi.baidu.com/xinghoney/blog/item/c61ede4c995247ffd62afc2f.html