今天在项目里,用了下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 331msplus 21msconcat 18msbuilder 12msbuffer 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; }看到这里感觉性能问题也没多大的意外了。