知乎上看到一个奇葩的性能测试,看了有点感兴趣,也自己测了一遍。 public static void main(String[] args) { long begin = System.currentTimeMillis(), end; List<StringBuffer> list = new ArrayList<>(); for (int i = 0; i < 10000000; i++) { StringBuffer str = new StringBuffer(); str.append("hello world." + i); list.add(str); } end = System.currentTimeMillis(); System.out.println(end - begin); }
代码本身没什么意义,不用纠结。这里关注的是 str.append("hello world." + i);
这一行。idea提示把括号里的“+”号替换成append方法调用。我试了一下,结果花费的时间反而更长了。 原先运行大约4秒就完成了,替换了之后,需要花费4.6秒左右。StringBuffer的append方法是有synchronized修饰的,开销比较大,感觉还不如直接用+号拼接。 那么换成 StringBuilder 会如何呢?上面的代码,仅仅把 StringBuffer 换成 StringBuilder ,执行的时间从大约4秒缩短为大约3.7秒,有提升,但是就一点点。然后再把括号里的“+”换成 append,结果时间变成大约4.3秒。可见,在简单的场景下,append方法并没有优势。当然,这里面测试程序的问题占了很大一部分原因。StringBuilder 这些类是用于字符串的多次拼接的,而测试方法只拼接一次,但是却不断重复地创建StringBuilder ,那么该类的优势就完全显现不出来。 然而当我把代码改成: List<String> list = new ArrayList<>(); for (int i = 0; i < 10000000; i++) { list.add("hello world." + i); }
执行所需的时间反而变成了5秒左右,还变长了。按知乎网友的说法,可能和垃圾回收机制有关。 另外,list = new ArrayList<>() 这里的初始化容量调大似乎对执行花费时间有反作用... |