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验证模式。 它还活着!!!

非常感谢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个网址无效:

我们看到,如果这是一个有效的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

java 微型数据库

java 微型数据库_Java 9代码工具:使用Java微型基准测试工具的实践会话相关推荐

  1. java xml 反射_Java 读取XML文件以及Java 的反射机制实现

    Java 读取XML文件以及Java 的反射机制实现 代码部分 import java.io.File; import javax.xml.parsers.DocumentBuilder; impor ...

  2. java servlet 数据库_Java Servlet调用数据库复习

    首先要导入jar包. 剩下的基本就是模版式的代码了: public class main { // JDBC 驱动名及数据库 URL static final String JDBC_DRIVER = ...

  3. java显示数据库_java查询数据库中的数据并显示

    java查询数据库中的数据并显示 关注:93  答案:2  mip版 解决时间 2021-01-17 16:29 提问者笑低了眉眼 2021-01-17 04:11 button.addSelecti ...

  4. java连连看倒计时_java连连看代码

    连连看JAVA源代码是什么? import javax.swing.*; import java.awt.*; import java.awt.event.*; public class lianli ...

  5. java derby数据库_使用Apache Derby进行Java数据库开发,第1部分

    java derby数据库 JDBC简介 以前,本系列文章通过使用ij工具连接Apache Derby数据库并与之交互来演示了许多数据库概念. 尽管当时可能还不太明显,但是您使用的Java应用程序使用 ...

  6. java derby数据库_使用Apache Derby进行Java数据库开发,第3部分

    该"使用Apache Derby进行Java数据库开发"系列的上一篇文章向您展示了如何使用Java Statement对象在Apache Derby数据库上执行SQL SELECT ...

  7. java必学_Java基础系列之初识JAVA

    工欲善其事必先利其器,在学习Java之初,大家一定要先了解下java的历史,以及找到一个适合自己的学习方法!很多同学在自学或者听课之初,完全不建议你直接使用一些IDE工具去写程序!自己先动手完全是很有 ...

  8. java属性绑定_java基础:10.1 Java FX与属性绑定

    图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. JavaFX作为Java新一代的GUI编程框架,受到Java ...

  9. java api教程_Java api 入门教程 之 JAVA的文件操作

    I/O类使用 由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择.因为文件是一种常见的数据源,而且读写文件也是程序员进行IO编程的一个基本 ...

最新文章

  1. 我的关于前端一些知识点的理解《一》
  2. 了解这3点,你也能成为出色的Java工程师!
  3. 文件目录管理与显示c语言,Centos 7 文件和目录管理
  4. 2018南京区域赛 J-Prime Game
  5. spring-boot 加载本地静态资源文件路径配置
  6. VS2015编译的OpenJDK8,会崩溃
  7. html5小说阅读器源码,文本源码阅读器(NexusTextView)
  8. libcurl - curl_easy_getinfo - 从 curl 句柄中提取信息 - 可用信息
  9. Contextual Word Embeddings
  10. python学习笔记六
  11. CPLEX运行出错-OPL标记问题
  12. ListView演练 - 带有组头的汽车品牌展示
  13. python生成vcf通讯录文件
  14. java找最长连续号段,字符串—寻找最长连续子串
  15. 【英语】美式元音 总结
  16. lisp语言与python_Lisp 语言优点那么多,为什么国内很少运用?
  17. android动画知乎,GitHub - ryanhoo/Zhihu-Parallax-Animation: 知乎 Android 客户端启动页的视差动画效果实现...
  18. 狄克斯特拉(Dijkstra)算法详解
  19. oh-my-zsh安装教程
  20. Oracle Synonym and Grant

热门文章

  1. CF1063F-String Journey【SAM,线段树】
  2. CF932F-Escape Through Leaf【树上启发式合并,CDQ分治,斜率优化dp】
  3. P2900-[USACO08MAR]Land AcquisitionG【斜率优化】
  4. P4130,jzoj1214-[NOI2007]项链工厂【线段树】
  5. 【斜率优化】玩具装箱(luogu 3195)
  6. 11、mybatis的功能架构分析
  7. 这几道 Redis 面试题都不懂,怎么拿 Offer?
  8. 深入探索 Java 热部署
  9. Executor 与 ExecutorService 和 Executors 傻傻分不清
  10. 部署shiro官方源码时,执行maven命令出错