今天在项目里,用了下String.format来格式化字符串,这样写好处时代码量少了那么一点且比较直观,但想想,为啥很少地方有用,是不是性能不好?然后写了以下的代码,比较下常用拼接方法的性能比较。
public class Test{
public static void main(String[] args){
long st = 0l,et=0l;
st= System.nanoTime();
for(int i=0;i<100000;i++){
Test.format("Tim",12);
}
et= System.nanoTime();
System.out.println("format "+(et-st)/1000000+"ms");
st= System.nanoTime();
for(int i=0;i<100000;i++){
Test.plus("Tim",12);
}
et= System.nanoTime();
System.out.println("plus "+(et-st)/1000000+"ms");
st= System.nanoTime();
for(int i=0;i<100000;i++){
Test.concat("Tim",12);
}
et= System.nanoTime();
System.out.println("concat "+(et-st)/1000000+"ms");
st= System.nanoTime();
for(int i=0;i<100000;i++){
Test.builder("Tim",12);
}
et= System.nanoTime();
System.out.println("builder "+(et-st)/1000000+"ms");
st= System.nanoTime();
for(int i=0;i<100000;i++){
Test.buffer("Tim",12);
}
et= System.nanoTime();
System.out.println("buffer "+(et-st)/1000000+"ms");
}
static String format(String name,int age){
return String.format("我叫%s,今年%d岁",name,age);
}
static String plus(String name,int age){
return "我叫"+name+",今年"+age+"岁";
}
static String concat(String name,int age){
return "我叫".concat(name).concat(",今年").concat(String.valueOf(age)).concat("岁");
}
static String builder(String name,int age){
StringBuilder sb=new StringBuilder();
sb.append("我叫").append(name).append(",今年").append(age).append("岁");
return sb.toString();
}
static String buffer(String name,int age){
StringBuffer sb=new StringBuffer();
sb.append("我叫").append(name).append(",今年").append(age).append("岁");
return sb.toString();
}
}
测试结果是:
format 331ms
plus 21ms
concat 18ms
builder 12ms
buffer 22ms
除了String.format外,其他都在意料之内。String.format的耗时也太超出想像了吧。
然后看了下实现的代码。
public Formatter format(Locale l, String format, Object ... args) {
ensureOpen();
// index of last argument referenced
int last = -1;
// last ordinary index
int lasto = -1;
FormatString[] fsa = parse(format);
for (int i = 0; i < fsa.length; i++) {
FormatString fs = fsa[i];
int index = fs.index();
try {
switch (index) {
case -2: // fixed string, "%n", or "%%"
fs.print(null, l);
break;
case -1: // relative index
if (last < 0 || (args != null && last > args.length - 1))
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[last]), l);
break;
case 0: // ordinary index
lasto++;
last = lasto;
if (args != null && lasto > args.length - 1)
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[lasto]), l);
break;
default: // explicit index
last = index - 1;
if (args != null && last > args.length - 1)
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[last]), l);
break;
}
} catch (IOException x) {
lastException = x;
}
}
return this;
}
看到这里感觉性能问题也没多大的意外了。