Java 9代码工具:使用Java微型基准测试工具的实践会话

用肉眼看,基准测试似乎只是确定执行某些代码需要花费多长时间的简单问题。 但是通常,这是幼稚的方法。 提供具有准确和可重复结果的有意义的基准并非易事。

在本文中,我们想向您介绍OpenJDK代码工具项目,尤其是JMH。 Java Microbenchmarking线束。 我们已经意识到它已有一段时间了,但是当我们看到它将在Java 9的开发中广泛使用时,它再次引起了我们的注意。

基准测试挑战

那么,为什么t2-t1的普通计时样式不起作用? 除非您正在监视实时系统,否则有许多因素可能会影响基准测试结果并使它们无效。 如果您没有使用像JMH这样的标准化基准测试工具,结果通常会令人怀疑。 并且不要忘记常识。 最重要的因素是常识 。

通常,问题是由特定的系统和VM优化引起的,这些优化可能会使结果在一个经过测试的用例中倾斜,而在另一个测试用例中不起作用。 为了最好或最坏。 诸如意外的GC,预热时间,消除死代码,各种JIT编译器优化,运行时差异,CPU怪癖等问题一直存在。 所有不一定与要进行基准测试的实际因素相关的因素。

哪个…是根据图灵奖获得者Donald Knuth的流行语录创建的:

舰船

要更深入地了解JMH如何解决这些问题,请查看Aleksey Shipilev的演讲和博客 。

JMH入门

设置您的项目使用JMH可以通过两种方式完成,作为一个独立项目,或者通过使用maven将依赖项添加为现有项目的一部分。 有关说明可在此处的官方页面上找到 。 顺便说一下,JMH还支持其他JVM语言,例如Scala,Groovy和Kotlin。

设置好环境后,就该移到实际的代码了。 JMH是一个注释驱动的框架,下面通过一个示例让我们看看它的含义。

基准测试示例:比较URL验证

在此测试中,我们将比较两种使用Java验证URL的不同方法:

1.使用java.net.URL构造函数。 如果构造函数由于URL无效而失败,则将引发MalformedURLException。 为了使测试更有趣,还添加了两个变体,将堆栈跟踪深度限制为6种方法,并完全取消了堆栈跟踪。

2.使用正则表达式,至少可以说是一个非常可怕的正则表达式,穆哈哈。 如果该网址不符合该格式,则我们认为该网址无效。

结果将帮助我们对这个问题有一个明确的答案,因此是时候下注了。 如果您在下面的评论部分中弄错了,请告诉我们:)

怪物正则表达式! URL验证模式。它还活着!!!

怪物正则表达式! URL验证模式。 它还活着!!!

非常感谢Hardy Ferentschik ,他让我们与Takipi博客读者分享了他的用例。 Hardy是RedHat的首席工程师,在Hibernate团队工作,还是Hibernate Validator的项目负责人。

基准测试的完整源代码可在GitHub上找到 。 我们建议在最接近的选项卡中将其打开,并将本节的其余部分用作参考手册。

1.基准设置

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1)
@Measurement(iterations = 2)
@OutputTimeUnit(TimeUnit.NANOSECONDS)

这是发生了什么的解释:

@BenchmarkMode
首先,选择我们要使用的基准测试模式。 JMH为我们提供了4种不同的模式: 吞吐量AverageTimeSampleTime (包括百分位数)和SingleShotTime (一次运行一个方法)。 这些的任何组合也是完全合法的。

@Warmup(迭代次数= 1)
预热迭代次数。

@Measurement(迭代次数= 2)
实际测量迭代次数。 在此示例基准测试中,我们进行了2次迭代,然后取平均分。

@OutputTimeUnit(TimeUnit.NANOSECONDS)
输出结果的时间单位,即对您有意义的java.util.concurrent.TimeUnit的任何值。

2.基准范围–初始状态

设置好之后,我们需要设置基准的初始状态。 在这种情况下,它包括我们将要测试的URL,正则表达式测试的类和URL构造函数测试的类。

每个此类都应使用@State(Scope.Benchmark)进行注释。

另外,对于URL列表,请注意@Param批注,用于将不同的值提供给基准:

@State(Scope.Benchmark)public static class URLHolder {@Param(value = {// should match"http://foo.com/blah_blah","http://142.42.1.1:8080/","http://例子.测试",// should not match"http//foo/","///a",":// should fail"})String url;
}

3.基准代码

现在我们已经设置好配置和初始状态,我们可以前进到实际的基准代码了。

@Benchmark
@Fork(1)
public boolean regExp(ValidateByRegExp validator, URLHolder urlHolder) {return validator.isValid( urlHolder.url );
}

@基准
将此方法标记为基准。

@叉(1)
要运行的试验次数。 每次运行都在不同的JVM中开始。 通过此批注,您还可以提供要包含在测试中的JVM参数。 因此,对于有限的堆栈跟踪测试,我们看到正在使用@Fork(value = 1,jvmArgs =“ -XX:MaxJavaStackTraceDepth = 6”)

4.运行测试

使用选项模式:

public static void main(String[] args) throws Exception {Options opt = new OptionsBuilder().include( ".*" + URLConstraintBenchmark.class.getSimpleName() + ".*" ).build();new Runner( opt ).run();
}

**这绝不是一个完整的指南,只是一个快速的教程,可以帮助您熟悉这些概念。 有关完整的示例集,请在此处查看官方的OpenJDK示例代码。

结果

如果您感到好奇,请以纳秒为单位报告结果。 是时候看看您的赌注是否正确了。 前3个网址合法,后3个网址无效:

JMH结果

我们看到,如果这是一个有效的URL,则验证的正则表达式非常糟糕。 在我们所有的有效网址中,它收到的效果最差。 另一方面,我们看到如果URL无效,则表将旋转,并且正则表达式将获得最佳结果。

在URL构造器方面,我们看不到有效URL的显着差异。 每个变体都提供几乎相同的结果,领先于正则表达式。 对于添加了MalformedURLException的无效URL,还有另一件事需要考虑:异常的堆栈跟踪。 相对于干净的(正则表达式)正则表达式版本,放慢了操作速度。

那么最好的选择是什么? 假设您的大多数数据都包含有效的URL,则URL构造函数的工作方式将是最好的。 尽管在某些情况下使用正则表达式可能会更好,但是如果您假设绝大多数URL都是无效的。

谁使用JMH对其代码进行基准测试?

首先,JMH被构建为OpenJDK项目的内部代码工具。 正如Oracle Java性能专家,JMH项目负责人Aleksey Shipilev告诉我们的那样:

“ JMH摸索着自己的痒:OpenJDK本身的性能工作。 因此,我们有许多特定于功能的基准,用于评估开发中代码的性能。 JMH驱动的基准测试报告了许多性能错误,以展示我们所看到的行为,并提供简单的测试用例来验证JDK更改。”

正如我们所讨论的那样,由于基准测试的准确性主要取决于它如何处理系统行为的各种优化和变化,因此没有比OpenJDK团队更好的团队来构建这种工具。 构建JVM的团队相同,其中包括大多数有用的(至今还很难进行基准测试)优化。

由于开发JMH的团队非常接近基础VM,因此它比其他工具更受青睐,并且可以在许多Java和Scala库和工具中使用。 一些著名的例子包括Twitter的Fingale和供生产使用 的其他 实用程序 , Jersey , Square Okio ,各种Apache项目,Hibernate等。

最后的想法

像许多其他核心Java问题一样,当涉及基准测试时,OpenJDK团队和资源通常是寻找答案的最佳场所。 JMH是一种易于使用的替代方法,可替代自家种植(且大多数情况下是错误的)微基准。 尽管这绝对不会使您摆脱常识来确保基准正确! 我们希望您发现该资源有用,并将继续探索使用JMH创建有意义的基准并与Java社区共享您的发现。 本周,我们还要分享在塔基皮(Takipi)取得的一些新进展。 如果您还没有看到实际的效果,那么这里是您入门所需的一切 。

翻译自: https://www.javacodegeeks.com/2015/11/java-9-code-tools-a-hands-on-session-with-the-java-microbenchmarking-harness.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vaadin_在Vaadin和JSF之间选择

vaadin随着最新版本的Primefaces 3.0的发布,JSF终于达到了前所未有的成熟度和实用性,使其与其他流行的Rich Internet Applications(RIA)选项面对面,例如Google Web Toolkit(GWT),Ext…

windows server 2008 oracle 10g,一次不太愉快的Windows Server 2008 R2 SP1上安装ORACLE 10G经历...

华为服务器型号RH5885 V3,安装windows server 2008 r2, oracle 10g1、安装包要使用10204_vista_w2k8_x64_production_db.zip,不用102010_win64_x64_database.zip;2、DBCA创建数据库之前,关闭BIOS中Hyper-Threading [ALL] - [Disab…

通过OmniFaces缓存组件以编程方式缓存PrimeFaces图表

在这篇文章中&#xff0c;您将看到如何结合PrimeFaces和OmniFaces获得可缓存的图表。 为了使事情变得简单&#xff0c;我们将使用PrimeFaces 折线图。 对于这种图表&#xff0c;我们可以在页面中使用<p&#xff1a;chart />标记和一个简单的托管bean。 因此&#xff0c;在…

ReactNative——打包发布

1、生成一个签名密钥 ‘ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 ’ 生成一个my-release-key.keystore的密钥库文件 2、找到路径/android/app/src/main,并在该目录下新建assets文件夹 3、在工程…

oracle版本说明,Oracle版本说明

Oracle 的版本号很多&#xff0c;先看11g的一个版本号说明&#xff1a; 注意&#xff1a; 在Oracle 9.2 版本之后&#xff0c; oracle 的maintenance release number 是在Oracle的版本号很多&#xff0c;先看11g的一个版本号说明&#xff1a;注意&#xff1a;在Oracle 9.2版本之…

Opserver配置Redis、SqlServer监控

简介 Opserver是Stack Overflow的开源监控解决方案&#xff0c;由Stack Exchange发布&#xff0c;基于.NET框架构建。开源地址&#xff1a;https://github.com/opserver/Opserver 使用 github下载源代码编译后&#xff0c;发布至IIS&#xff0c;需要先修改Opserver/Config目录下…

Linux挂载多个文件夹读不出,FTP不显示Linux挂载文件夹怎么办?-处理FTP不显示Linux挂载文件夹的方案 - 河东软件园...

最近有位用户向小编反映&#xff0c;声称自己在Linux中使用vsftpd启FTP服务&#xff0c;并在FTP用户下挂载一个Windows的共享盘&#xff0c;但是登陆FTP后却无法显示该挂载的共享盘。出现这种问题真是令人十分头疼呢&#xff0c;想要快速解决这个问题又找不到合适的方法。该怎么…

以太坊智能合约Hello World示例程序

简介 以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开发应用&#xff0c;首先需要安装其客户端&#xff0c;本文使用基于Go语言的Geth, 其官网为https://github.c…

Java到LDAP教程(包括如何安装LDAP服务器/客户端)

本教程将向您展示如何编写Java代码以与LDAP交互。 但是在执行此操作之前&#xff0c;我们需要在计算机上设置LDAP服务器和客户端。 如果此时您不确定到底是什么LDAP&#xff0c;建议您参考这篇文章&#xff0c;其中提供了一个很好的定义示例。 &#xff08;简而言之&#xff0…

在linux下赋予000权限,【linux】对于文件权限的理解

本篇博文旨在介绍linux下的权限问题&#xff1b;介绍了Linux下&#xff0c;查看权限、修改权限等方法&#xff1b;并通过分别在超级用户(root)和普通用户下进行测试&#xff0c;探索不同等级的用户进入目录需要的权限&#xff0c;以及进入后&#xff0c;显示和创建文件需要的权…

手把手教你制作简易计算器

实现过程&#xff1a; HTMLCssJS 具体通过标签实现计算器整个的框架 通过Css样式实现计算器页面布局及框架优化 通过JavaScript算法实现计算器计算过程 次实验过程&#xff1a; 背景图片背景音乐&#xff08;看个人意愿加&#xff01;&#xff09; 安排&#xff1a; <!--HT…

安装tron_具有Tron效果的JavaFX 2 Form

安装tron这是一个具有TRON效果的简单JavaFX登录表单。 在此示例中&#xff0c;我使用CSS设置TextField和Button的样式。 这是CSS和Effect代码的片段&#xff1a; .text-field{-fx-background-color: transparent;-fx-border-color: #00CCFF;-fx-text-fill: white; }.password-f…

在Spring 4.2中更简单地处理异步事务绑定事件

介绍 如您可能已经知道的&#xff08;例如&#xff0c;从我以前的博客文章中 &#xff09;&#xff0c;不再需要创建一个单独的类&#xff0c;该类使用onApplicationEvent方法实现ApplicationListener以便能够对应用程序事件做出响应&#xff08;包括来自Spring Framework本身和…

linux chattr 无权限,从零开始学习Linux(二十八):文件权限之chattr权限

1、chattr命令命令格式&#xff1a; chattr [-] [选项] 文件名或者目录名&#xff1b;参数说明&#xff1a;&#xff1a;增加权限&#xff1b;-&#xff1a;删除权限&#xff1b; 等于某权限&#xff1b;选项说明&#xff1a;i&#xff1a;如果对文件设置i属性&#xff0c;则不…

初等数论及其应用——中国剩余定理

在线性代数中&#xff0c;我们用高斯消元解决多元的线性方程组&#xff0c;而在数论中&#xff0c;面对一元变量的线性模方程组&#xff0c;我们利用中国剩余定理去求解x。 转载于:https://www.cnblogs.com/rhythmic/p/5928483.html

linux c 11 运行库,11.1.3 运行库与I/O

11.1.3 运行库与I/O在了解了glibc和MSVC的入口函数的基本思路之后&#xff0c;让我们来深入了解各个初始化部分的具体实现。但在具体了解初始化之前&#xff0c;我们要先了解一个重要的概念&#xff1a;I/O。IO(或I/O)的全称是Input/Output&#xff0c;即输入和输出。对于计算…

linux windows 丢失,Win10预览版9879硬盘丢失的Linux解决方案

IT之家讯 12月3日消息&#xff0c;最近IT之家论坛网友九仙仙总结了Win10预览版9879硬盘问题的解决方法&#xff0c;并在论坛中发布出来。经测试&#xff0c;此为快速有效的解决方法&#xff0c;故公之于众供朋友们参考。以下为作者原文。开头说明两点&#xff1a;1、这是我个人…

Android开发——Android系统启动以及APK安装、启动过程

0. 前言 从Android手机打开开关&#xff0c;到我们可以使用其中的app时&#xff0c;这个启动过程到底是怎么样的&#xff1f;1. 系统上电当给Android系统上电&#xff0c;在电源接通的瞬间&#xff0c;CPU内的寄存器和各引脚均会被置为初始状态&#xff0c;CPU复位之后&#…

linux生成文件清单,Linux 获取文件名称生成列表 txt - create_filelist

Linux 获取文件名称生成列表 txt - create_filelist1. find/home/strong/MOTChallenge/MOT16/MOT16/train/MOT16-04/img1/ 文件夹下所有 *.jpg (000001.jpg - 001050.jpg) 的路径 图片名信息写入 txt 文件。1.1 llstrongforeverstrong:~/MOTChallenge/MOT16/MOT16/train/MOT16…

jvm线程分析命令_JVM:如何分析线程转储

jvm线程分析命令本文将教您如何分析JVM线程转储&#xff0c;并查明问题的根本原因。 以我的观点&#xff0c;线程转储分析是掌握Java EE生产支持的任何个人最重要的技能。 您可以从线程转储快照中获取的信息量通常远远超出您的想象。 我的目标是与您分享我在过去10年中积累的有…