我运行了以下JUnit测试用例,并且能够为Stringbuffer
持续获得比StringBuilder
更好的性能结果。我确信我在这里遗漏了一些东西,但我找不到为什么StringBuffer
比StringBuilder
获得更好速度的原因。
我的测试用例是,
@Test
public void stringTest(){
String s1 = "s1";
String s2 = "s2";
for(int i=0;i<=100000;i++){
s1 = s1+s2;
}
System.out.println(s1);
}
@Test
public void stringBuilderTest(){
StringBuilder s1 = new StringBuilder("s1");
String s2 = "s2";
for(int i=0;i<=100000;i++){
s1.append(s2);
}
System.out.println(s1);
}
@Test
public void stringBufferTest(){
StringBuffer s1 = new StringBuffer("s1");
String s2 = "s2";
for(int i=0;i<=100000;i++){
s1.append(s2);
}
System.out.println(s1);
}
请查找JUnit测试结果
正如您在上面的结果{$ 1}}中看到的那样,案件的执行速度早于stringBufferTest
。我的问题是为什么会这样?我知道这在理论上是不可能的,但我是如何得到这个结果的?
更新
根据@ Henry的评论,我删除了SysOuts,结果发生了巨大变化。
然后我将循环次数增加100000 - &gt; 1000000并且能够得到一些我一直期待的真实结果,
我的新问题是,
答案 0 :(得分:2)
我担心您的基准测试基本无效。
Microbenchmarks(小代码,相对较快地完成)很难用Java(以及许多其他语言)来实现。使这些基准难以解决的一些问题:
Oracle的这篇文章详细介绍了这些问题:http://www.oracle.com/technetwork/articles/java/architect-benchmarking-2266277.html
最后,归结为:除非你对此非常有经验,否则不要从头开始编写微基准。您获得的结果与该代码在实际应用程序中的执行方式无关。
使用类似JMH(Java Microbenchmark Harness)的框架。我上面链接的文章包含JMH的介绍,但也有其他教程(例如http://java-performance.info/jmh/)。
投入一些时间学习使用JMH。这很值得。当您使用JMH运行基准测试时,您将在其输出中看到基准时间由于JVM优化而发生的变化(JMH多次调用您的测试)。
如果在JMH中运行StringBuilder与StringBuffer测试,您应该会发现两个类在现代CPU上的执行情况大致相同。 StringBuilder稍微快一点,但不是那么多。不过,我会使用StringBuilder,因为它稍快一些。