几个月前,我写了一篇文章比较循环的短索引的性能 。 我问自己关于使用短裤作为循环迭代次数很少的循环的性能。

在Java语言中,所有对整数的操作都是int进行的。 因此,如果我们使用short作为循环索引,则在每次迭代时都将进行类型转换,这实际上比对int的简单影响要重。

我编写该代码来实现我的目标:

package com.wicht.old;public class TestShortInt {public static void main(String[] args){long startTime = System.nanoTime();int resultInt = 0;for (int i = 0; i < 100000; i++){for (int j = 0; j < 32760; j++){resultInt += i * j;}}System.out.println("Temp pour int : " + (System.nanoTime() - startTime) / 1000000 + " ms");startTime = System.nanoTime();int resultShort = 0;for (int k = 0; k < 100000; k++){for (short f = 0; f < 32760; f++){resultShort += k * f;}}System.out.println("Temp pour short : " + (System.nanoTime() - startTime) / 1000000 + " ms");System.out.println(resultInt);System.out.println(resultShort);}
}

结果我发现short比int慢了两倍,直到一周前我才确信这些结果。

这时,一位读者(Jean)批评了我的测试结果,并给了我有关微基准测试的几篇文章的链接。 我阅读了这些文章,并了解了为什么我的结果不正确。

实际上,我的测试没有注意可能改变测试结果的几件事:

  • JVM预热 :由于有几个参数,代码通常通常会很慢,并且随着执行时间的增长直到达到稳态,代码会变得越来越快。
  • 类加载 :第一次启动基准测试时,必须加载所有使用的类,从而增加了执行时间。
  • 即时编译器 :当JVM识别出代码的重要部分时
  • 垃圾收集器 :在基准测试期间可能会发生垃圾收集,并且时间会大大增加。

由于所有这些因素,第一次运行(可能需要运行10秒)比其他运行速度慢,并且会使基准完全错误。

那么,我们如何才能取得良好的基准测试结果呢?

这确实很困难,但是我们可以使用Elliptic Group的软件开发人员Brent Boyer引入的基准框架获得帮助。 该框架照顾了所有先前引入的因素,并制定了良好的基准。

该框架的使用非常简单,您只需创建Benchmark类的新实例,并将其传递给Callable或Runnable即可,然后直接启动测试。 这是在循环索引中测试short和int的示例:

public class ShortIndexesLoop {public static void main(String[] args) {Callable callableInt = new Callable(){public Long call() throws Exception {long result = 0;for (int f = 0; f < 32760; f++){result += 444;}return result;}};Callable callableShort = new Callable(){public Long call() throws Exception {long result = 0;for (short f = 0; f < 32760; f++){result += 444;}return result;}};try {Benchmark intBenchmark = new Benchmark(callableInt);System.out.println("Result with int ");System.out.println(intBenchmark.toString());Benchmark shortBenchmark = new Benchmark(callableShort);System.out.println("Result short ");System.out.println(shortBenchmark.toString());} catch (Exception e) {e.printStackTrace();}}
}

要获得结果,可以使用Benchmark.toString()或Benchmark.toStringFull()获得更多统计信息。 您还可以使用Benchmark.getSd()直接访问某些统计信息(例如标准差),也可以直接使用Benchmark.getStats()获取所有统计信息。

这是前面代码的结果:

结果int first = 807.056 us,平均值= 46.032 us(CI delta:-261.393 ns,+408.932 ns),sd = 230.929 us(CI delta:-68.201 us,+105.262 us)
结果短短优先= 721.912 us,平均值= 48.234 us(CI delta:-198.625 ns,+254.774 ns),sd = 160.196 us(CI delta:-32.764 us,+37.882 us)

如您所见,短版本仅比int慢104.78%。 这表明最初的结果是完全错误的。

这是int版本的完整结果:

动作统计信息:第一个= 807.056 us,平均值= 46.032 us(CI delta:-261.393 ns,+408.932 ns),sd = 230.929 us(CI delta:-68.201 us,+105.262 us)警告:执行时间有极端异常情况,标清值可能不准确---根据块统计信息计算操作统计信息-每个块测量32768个任务执行-用户说任务内部执行m = 1个动作-那么每个块测量的动作数为a = 32768-阻止统计信息:平均值= 1.508 s(CI增量:-8.565毫秒,+ 13.400毫秒),sd = 41.803毫秒(CI增量:-12.346毫秒,+ 19.054毫秒)–用于将阻止统计信息转换为行动统计信息的论坛(均值)假设a / a为1 / s,则sd缩放为1 / sqrt(a))假定操作执行时间为iid — —每个置信区间(CI)被报告为点估计的+-增量或封闭点间隔([x,y])–每个置信区间的置信度为0.95 — —-–执行时间显示在外边的情况–使用箱线图确定 中位数= 1.498 s,interquantileRange = 34.127 ms的算法– 3是极度(偏高):#57 = 1.621 s,#58 = 1.647 s,#59 = 1.688 s –2是温和的(偏高): #55 = 1.570 s,#56 = 1.582 s ———-阻止sd值可能无法反映任务的内在变化–猜测:环境噪声至少解释了所测量sd的55.89418621876822%———- –动作sd值几乎完全相同由离群值填充–根据等值离群值模型,它们至少导致了98.95646276911543%的已测量方差–模型数量:a = 32768.0,muB = 1.5083895562166663,sigmaB = 0.04180264914581472,muA = 4.603239612477619E-5,sigmaA = 2.3092919283255957E- 4,tMin = 0.0,muGMin = 2.3016198062388096E-5,sigmaG = 5.754049515597024E-6,cMax1 = 1252,cMax2 = 322,cMax = 322,cOutMin = 322,varOutMin = 0.0017292260645147487,muG(cOutMin)= 2.3034259031465023E-5, U(cOutMin)= 0.002363416110812895

就像您在使用此框架时可能看到的那样,当您举例说明您存在极端异常值可能使标准偏差完全错误时,它会向您发出一些警告。

您可以在Elliptic Group的网页上下载此框架。 我发现它非常强大且易于使用,并且每次需要进行基准测试时都会使用它。

总而言之,我还必须说,即使您使用那种框架,如果您没有测试代码的正确部分,也可能会导致非常糟糕的基准测试。 这是来自Brent Boyer的两篇非常有趣的文章:

  • 健壮的Java基准测试,第1部分:问题
  • 强大的Java基准测试,第2部分:统计信息和解决方案

参考: 如何通过 @Blog(“ Baptiste Wicht”)的 JCG合作伙伴 Baptiste Wicht 编写正确的基准 。

相关文章 :
  • 绩效焦虑–关于绩效不可预测性,度量和基准
  • 改善Java应用程序性能的快速技巧
  • 如何在Java中获得类似于C的性能
  • Java中的低GC:使用原语而不是包装器
  • 如何在不到1ms的延迟内完成100K TPS

翻译自: https://www.javacodegeeks.com/2011/09/java-micro-benchmarking-how-to-write.html

Java Micro-Benchmarking:如何编写正确的基准相关推荐

  1. 如何在Java中编写正确的微基准测试?

    您如何用Java编写(并运行)正确的微基准测试? 我正在寻找一些代码示例和注释,以说明要考虑的各种问题. 示例:基准测试应测量时间/迭代或迭代/时间,为什么? 相关: 秒表基准测试是否可以接受? #1 ...

  2. 《Java编码指南:编写安全可靠程序的75条建议》—— 指南20:使用安全管理器创建一个安全的沙盒...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议>一书中的第1章,第1.20节,作者:[美]Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达 ...

  3. 《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.7 修复错误...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议(英文版)>一书中的第2章,第2.7节,作者:[美]Fred Long(弗雷德•朗),Dhruv Mohindra(德鲁• ...

  4. 在java中开发图形用户_2016年计算机二级考试《JAVA》习题:编写图形用户界面

    第9章 编写图形用户界面 1[单选题]哪个布局管理器使用的是组件的尺寸? ( ) A.FlowLayout B.BorderLayoutC.GridLayout D.CardLayout 参考答案:A ...

  5. 在JAVA语言程序中main_在Java程序main方法中,正确的参数是

    [单选题]下列叙述中,错误的是 [填空题]Access属于()数据库,Access中,不允许在主关键字字段中有重复值或(). [单选题]如下哪些字符串是Java中的标识符? [填空题]常用的基本电量传 ...

  6. Java Micro Framework:您无法忽略的新趋势

    什么是Java微框架,为什么要使用它们? 每种语言都有权衡. 对于Java,要成为一种安全,经过严格测试,向后兼容的语言,就要在敏捷性和精简性方面做出一些牺牲. 毫无疑问,它有一些冗长和冗长的内容,但 ...

  7. java面试题32:Java网络程序设计中,下列正确的描述是()

    java面试题32:Java网络程序设计中,下列正确的描述是() A:Java网络编程API建立在Socket基础之上 B:Java网络接口只支持tcP以及其上层协议 C:Java网络接口只支持UDP ...

  8. Java 并发编程解析 | 如何正确理解Java领域中的锁机制,我们一般需要掌握哪些理论知识?

    苍穹之边,浩瀚之挚,眰恦之美: 悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 提起Java领域中的锁,是否有种"道不尽红尘奢恋,诉不完人间恩怨"的 ...

  9. 08从零开始学Java之记事本怎么编写Java代码?

    作者:孙玉昌,昵称[ 一一哥],另外[ 壹壹哥]也是我哦 CSDN博客专家.万粉博主.阿里云专家博主.掘金优质作者 配套开源项目资料 GitHub地址: https://github.com/SunL ...

最新文章

  1. sqlite--代码操作
  2. 卫星轨道推演计算相关知识点总结(含欧拉角、旋转矩阵、及各坐标系转化等)
  3. Eureka 服务注册与发现02——集群版
  4. 几十万实例线上系统的抖动问题定位
  5. jmeter中重定向多个正则表达式_2020年jmeter技术实战续集,最新技术全栈,值得收藏
  6. NET问答: String 和 string 到底有什么区别?
  7. linux中usb设备名,Linux 中识别 USB 设备名字的 4 种方法
  8. TCP与UDP的选择--结合QQ来说明
  9. java yaml dump方法_yamlyaml.load与yaml.dump方法
  10. 场景联创 施耐德电气“绿色智能制造创赢计划”第二季收官
  11. puppeteer执行js_使用Node.js和Puppeteer与表单和网页进行交互– 1
  12. Linux rmdir命令:删除空目录
  13. php获取模型错误,php – 解析错误,期望activecollab模型类中出现“T_PAAMAYIM_NEKUDOTAYIM”错误...
  14. Prototype 学习——Function对象
  15. RMAN数据库恢复 之归档模式有(无)备份-丢失数据文件的恢复
  16. 约束布局管理器 CAConstraintLayoutManager 以及其不起作用
  17. 1.企业应用架构模式 --- 分层
  18. 怎么调linux系统的屏幕刷新率,怎么改屏幕的刷新率?
  19. 算法谜题1,狼羊菜过河
  20. webpack出现CssSyntaxError

热门文章

  1. java泛型程序设计——注意擦除后的冲突
  2. spring 配置只读事务_只读副本和Spring Data第1部分:配置数据库
  3. java获得电脑性能_Java:使用SingletonStream获得性能
  4. 单例模式引发的内存泄漏:_资源泄漏:救援的命令模式
  5. 古巴比伦乘法_古巴平台中的通用过滤器–类固醇上的excel过滤器
  6. 注释嵌套注释_注释,无处不在的注释
  7. 如何在Java中将数组转换为列表
  8. 使用Oracle验证外部数据
  9. 非一致性访存系统_Hibernate事实:访存策略的重要性
  10. maven检测依赖_检测Maven依赖中介