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
综上,还是傻傻的什么都不想,用最原始的方式吧,哈哈...
相关文章推荐
- 选定虚拟主机 性能凸显优势
- 修改一行代码提升 Postgres 性能 100 倍
- redis的hGetAll函数的性能问题(记Redis那坑人的HGETALL)
- 推荐Sql server一些常见性能问题的解决方法
- SQL Server误区30日谈 第9天 数据库文件收缩不会影响性能
- 和表值函数连接引发的性能问题分析
- SQLServer 2000 升级到 SQLServer 2008 性能之需要注意的地方之一
- 在C#的类或结构中重写ToString方法的用法简介
- 数据库性能优化三:程序操作优化提升性能
- VBS中的字符串连接的性能问题
- mysql 性能的检查和调优方法
- 数据库性能优化二:数据库表优化提升性能
- SQL语句性能优化(续)
- SQL语句优化提高数据库性能
- 如何用分表存储来提高性能 推荐
- ASP中使用FileSystemObject时提高性能的方法
- 全面解析JavaScript中的valueOf与toString方法(推荐)
- 如何改进javascript代码的性能
- JavaScript函数中关于valueOf和toString的理解
- JavaScript脚本性能优化注意事项