您的位置:首页 > 编程语言 > Java开发

Java toString的性能优化方案比较

2016-07-17 23:22 513 查看

Java toString的性能优化方案比较

通常toString重写会优先使用StringBuffer来进行append,但jdk1.7以上,已经做了充分优化,让我们通过实际测试数据,来对比下是否String的concat(+)是否真的会差呢?

测试环境,JUnit和JMH(JMH相关资料请自行百度),相关Maven依赖如下:

<!-- 测试部分-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.12</version>
<scope>provided</scope>
</dependency>


首先基于通用的System的当前时间进行测试,测试代码如下:

public String toStringConcat() {
return "ToStringTest{" +
"att1='" + att1 + '\'' +
", att2='" + att2 + '\'' +
", att3='" + att3 + '\'' +
'}';
}

public String toStringSb() {
final StringBuffer sb = new StringBuffer("ToStringTest{");
sb.append("att1='").append(att1).append('\'');
sb.append(", att2='").append(att2).append('\'');
sb.append(", att3='").append(att3).append('\'');
sb.append('}');
return sb.toString();
}

public String toStringStringBuilder() {
final StringBuilder sb = new StringBuilder("ToStringTest{");
sb.append("att1='").append(att1).append('\'');
sb.append(", att2='").append(att2).append('\'');
sb.append(", att3='").append(att3).append('\'');
sb.append('}');
return sb.toString();
}


下面通过JUnit进行允许测试

/**
* 功能说明 :junit测试try性能
* @author  Zain 2016/7/14  10:28
* @return  result
* @params
*/
@Test
public void simpleTest() throws Exception {
System.out.println("toStringConcat ---------------------------------");
long startTime = System.currentTimeMillis();
try {
for (int i = 0; i < 1000000; i++) {
toStringConcat();
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("toStringConcat " + (endTime - startTime) + " milliseconds");

System.out.println("toStringSb ---------------------------------");
startTime = System.currentTimeMillis();
try {
for (int i = 0; i < 1000000; i++) {
toStringSb();
}
} catch (Exception e) {
e.printStackTrace();
}
endTime = System.currentTimeMillis();
System.out.println("toStringSb " + (endTime - startTime) + " milliseconds");

System.out.println("toStringStringBuilder ---------------------------------");
startTime = System.currentTimeMillis();
try {
for (int i = 0; i < 1000000; i++) {
toStringStringBuilder();
}
} catch (Exception e) {
e.printStackTrace();
}
endTime = System.currentTimeMillis();
System.out.println("toStringStringBuilder " + (endTime - startTime) + " milliseconds");

}


代码很简单,直接给测试结果:


toStringConcat ---------------------------------
toStringConcat 80 milliseconds
toStringSb ---------------------------------
toStringSb 374 milliseconds
toStringStringBuilder ---------------------------------
toStringStringBuilder 146 milliseconds


当然,每次运行结果可能不一样,由于JVM“热身”的原因,我们调整下运行顺序,将String的concat放到最后,运行结果如下:


toStringSb ---------------------------------
toStringSb 370 milliseconds
toStringStringBuilder ---------------------------------
toStringStringBuilder 235 milliseconds
toStringConcat ---------------------------------
toStringConcat 69 milliseconds


这里已经可以看到曾经邪恶的+,貌似更加高效,下面用JMH测试进一步有效验证。
测试代码如下:


@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void toStringConcatBenchmark() {
int j = 3;
try {
for (int i = 0; i < 1000000; i++) {
toStringConcat();
}
} catch (Exception e) {
e.printStackTrace();
}

}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void toStringSbBenchmark() {
int j = 3;
for (int i = 0; i < 1000000; i++) {
try {
toStringSb();
} catch (Exception e) {
e.printStackTrace();
}
}
}

@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void toStringStringBuilderBenchmark() {
int j = 3;
for (int i = 0; i < 1000000; i++) {
try {
toStringStringBuilder();
} catch (Exception e) {
e.printStackTrace();
}
}
}


JMH允许代码:


/**
* 功能说明 :JMH测试try性能
* @author  Zain 2016/7/14  10:29
* @return  result
* @params
*/
@Test
public void benchmarkTest() throws Exception {
Options opt = new OptionsBuilder()
.include(ToStringTest.class.getSimpleName())
.forks(1)
.build();
new Runner(opt).run();
}


运行结果:


# Run complete. Total time: 00:02:10
第一次
Benchmark                                     Mode  Cnt  Score    Error   Units
ToStringTest.toStringConcatBenchmark         thrpt   20  0.029 ±  0.001  ops/ms
ToStringTest.toStringSbBenchmark             thrpt   20  0.006 ±  0.001  ops/ms
ToStringTest.toStringStringBuilderBenchmark  thrpt   20  0.008 ±  0.001  ops/ms

第二次
Benchmark                                     Mode  Cnt  Score    Error   Units
ToStringTest.toStringConcatBenchmark         thrpt   20  0.029 ±  0.001  ops/ms
ToStringTest.toStringSbBenchmark             thrpt   20  0.006 ±  0.001  ops/ms
ToStringTest.toStringStringBuilderBenchmark  thrpt   20  0.007 ±  0.001  ops/ms


综上,还是傻傻的什么都不想,用最原始的方式吧,哈哈...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  toString 性能