在拼接字符串时我们通常会有两种方法,一种是用String
类重载‘+’运算符进行拼接,本质上是调用StringBuilder.append
。还有一种类似C的printf
风格,调用String.format()
,底层是调用formatter.format
方法。那从性能和内存占用两个方面考虑到底是哪一个方法更好呢?
做了一个小小的实验.注意测试的时候注释掉非测试方法,免得内存占用会被其他的方法影响.
class StringTest {
public static void main(String[] args) {
// testOperatorPlus();
//testAppend();
testFormat();
}
private static void testFormat() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 10000; i++) {
String s = String.format("Blah %d Blah %d Blah %d", i, i, i);
}
long ww=runtime.freeMemory();
time = System.currentTimeMillis() - prev_time;
memory = memory - ww;
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
private static void testAppend() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 10000; i++) {
sb.append("Blah ");
sb.append(i);
sb.append("Blah ");
sb.append(i);
sb.append("Blah ");
sb.append(i);
}
time = System.currentTimeMillis() - prev_time;
memory = memory - runtime.freeMemory();
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
private static void testOperatorPlus() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 1000000; i++) {
String s = "Blah " + i + "Blah " + i + "Blah " + i;
}
time = System.currentTimeMillis() - prev_time;
memory = memory - runtime.freeMemory();
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
}
结果如下:
Method | Time(ms) | Memory Usage(long) |
---|---|---|
‘+’ operator | 115 | 28805400 |
StringBuilder.append | 14 | 884768 |
String.foramt | 276 | 23175080 |
可以看到StringBuilder.append
的执行时间和内存占用都是最优的。'+'运算符比直接调用StringBuilder.append
要慢上不少,特别是要连接的字符串数量较多时,内存占用也特别大。String.format
由于每次都有生成一个Formatter
对象,较慢也是情理之中。
PS:测试数据少且缺少对比实验,结论适用性有限,仅供参考。
另见:http://stackoverflow.com/q/925423/5032462