这两天看到的关于Java的一篇文章(《阿里资深工程师教你如何优化Java代码》)中有写到使用String.valueOf(value)代替 “” + value的建议,原因是“当要把其他对象或类型转换为字符串时,使用String.valueOf(value)比""+value的效率更高。”
反例:
int i = 1;
String s = "" + i;
正例:
int i = 1;
String s = String.valueOf(i);
当看到上面的建议的时候是认同的,后来仔细一想Android framework上面log的写法都是下面的方式:
int num = 1;
int count = 2;
Rlog.d(LOG_TAG, "the num:" + num + ", the count:" + count);
而Rlog.d的原型函数如下:
\frameworks\base\telephony\java\android\telephony\Rlog.java
public static int (String tag, String msg) {
// native实现
}
函数实现上看,打印的日志信息就是String类型的,Android中的使用方法就是反例,效率不高。是不是应该改成
int num = 1;
int count = 2;
Rlog.d(LOG_TAG, "the num:" + String.valueOf(num) + ", the count:" + String.valueOf(count));
但是Android code中几乎看不到上面这种写法,那就奇怪了,Android中打印的log数量还是很可观的,尤其是测试版本上,log更是很多。那Android为什么不使用String.valueOf呢?难道Android错了?当问题提出后,我打算通过字节码看一下反例和正例的差别,另外就是通过实际测试看一下两种效率的差异。
有些问题通过字节码就能看出端倪。下面是需要转译字节码的原始code,比较常用,尤其是打印log,字符串和整数拼接出一个新的自付出。
public class TestValueOf {
public static void main(String[] args) {
int i = 0;
String s = "abcdef";
String s1 = s + i;
System.out.println(s1);
String d = "abcdef";
String d1 = d + String.valueOf(i);
System.out.println(d1);
}
}
下面是对应生成的字节码:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=6, args_size=1
0: iconst_0
1: istore_1
2: ldc #2 // String abcdef
4: astore_2
5: new #3 // class java/lang/StringBuilder
8: dup
9: invokespecial #4 // Method java/lang/StringBuilder.""?)V
12: aload_2
13: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: iload_1
17: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
20: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: astore_3
24: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
27: aload_3
28: invokevirtual #9 // Method java/io/PrintStr