下面两段代码String a = "abc";
Integer b = 1;
String c = null;
long begin = System.nanoTime();
for(int i = 0; i < 1000; i ++){
c = a + b;
}
System.out.println(System.nanoTime() - begin);String a = "abc";
int b = 1;
String c = null;
long begin = System.nanoTime();
for(int i = 0; i < 1000; i ++){
c = a + b;
}
System.out.println(System.nanoTime() - begin);第二段要比第一段快30%的样子,为什么?
我理解的是a+b的时候要把b自动装箱成Integer,然后toString,
按理说比第一段要慢,就算是编译的时候已经优化过了,
也不应该比第一段快才是?
Integer b = 1;
String c = null;
long begin = System.nanoTime();
for(int i = 0; i < 1000; i ++){
c = a + b;
}
System.out.println(System.nanoTime() - begin);String a = "abc";
int b = 1;
String c = null;
long begin = System.nanoTime();
for(int i = 0; i < 1000; i ++){
c = a + b;
}
System.out.println(System.nanoTime() - begin);第二段要比第一段快30%的样子,为什么?
我理解的是a+b的时候要把b自动装箱成Integer,然后toString,
按理说比第一段要慢,就算是编译的时候已经优化过了,
也不应该比第一段快才是?
而是String类中“+”的问题。
前一种方法c=a+b;相当于c=a+b.toString();
照成了for循环中一直在new String类型的对象
而后一种方法则涉及到了String类中的“+”运算符的问题:
Java只是不支持自定义运算符重载,这个String类的+就是运算符重载,
也是Java中仅有的一个运算符重载,它是通过编译器实现的,
在语法解析阶段就已经确定了
具体来说后一种方法
c=a+b;相当于c= new StringBuilder().append(a).append(b).toString();如果仅仅比较Integer().toString与1+“”的效率的话
前者的效率应该高些。
原因在于Integer().toString方法在java中实现了很多的优化
public class Test1 {
public static void main(String[] args) { Integer b = 1;
long begin = System.nanoTime();
System.out.println(b);
System.out.println(System.nanoTime() - begin);
}
}public class Test2 {
public static void main(String[] args) {
int b = 1;
long begin = System.nanoTime();
System.out.println(""+b);
System.out.println(System.nanoTime() - begin);
}
}
public void haha(){
String a = "abc";
Integer b = 1;
String c = null;
long begin = System.nanoTime();
for( i = 0 ; i < 1000; i ++){
c = a + b;
}
System.out.println(System.nanoTime() - begin);
System.out.println(c);
}
当循环增加到100000000次后与10000次的平均循环时间比其实有降低。
把两个.class文件分别用javap查看
关键的区别应该在第一段的+操作是(Integer)
33: invokevirtual #40; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
第二段的是(int)
30: invokevirtual #35; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
看了下源代码,append(Object)是需要把字符串的内容arraycopy一次,
append(int)只是把自己内部的char[]传到Integer的一个static方法里面,简单的拼在后面
也许是这个原因?
这个是把数字加大后visualvm的图,划掉的是System.in.read(),无视掉..
看起来主要区别就是append这个方法差很多..
Integer用的时间是20013-划掉的3195=16818
int用的时间14188-划掉的2294=11894
差值是4924
Integer的append-int的append=6255 - 1894=4361
88%的时间差都是这个方法造成的..
看来大概是这么个问题吧..
应该是Integer转String的代价要小些吧
Integer的toString()方法做了相关优化 Integer b = 1;
long begin = System.nanoTime();
System.out.println(b);
System.out.println(System.nanoTime() - begin); int b = 1;
long begin = System.nanoTime();
System.out.println(""+b);
System.out.println(System.nanoTime() - begin); 时间也是前一段代码执行的时间短一些啊
http://blog.sina.com.cn/s/blog_4b50130d0100u3vh.html优化的:
http://pnuts.cc/2010/01/int-to-string/comment-page-1/?replytocom=753
Integer b = 1;
long begin = System.nanoTime();
System.out.println("" + b);
System.out.println(System.nanoTime() - begin);
int c = 1;
begin = System.nanoTime();
System.out.println(""+c);
System.out.println(System.nanoTime() - begin);
}这个代码执行结果是
1
202202
1
41332
append(int)比append(Object)的效率高,
所以int b = 1的要比Integer b = 1的那段要快