成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Jmh基準測試,看我怎么用它來測試Mongodb的數據加載性能

開發 前端 MongoDB
最近我們這邊引入了mongodb,不過沒有實際上測試過性能如何,只是聽說讀寫比mysql快,你今天沒有什么排期,測試一下,然后今天內給我個答案吧!

 [[410165]]

本文轉載自微信公眾號「稀飯下雪」,作者帥氣的小飯飯 。轉載本文請聯系稀飯下雪公眾號。

「主管小肥肥:」 最近我們這邊引入了mongodb,不過沒有實際上測試過性能如何,只是聽說讀寫比mysql快,你今天沒有什么排期,測試一下,然后今天內給我個答案吧

「小飯飯:」 好的,接下來就是測試性能的一天了。

到了這里,可能大部分人的第一想法應該是直接用這種方式:

  1. public void test() { 
  2.     long start = System.currentTimeMillis(); 
  3.     // 執行邏輯 
  4.     long end = System.currentTimeMillis();   
  5.     System.out.println(end - start); 

no,我這次使用的是JMH

無論出自何種原因需要進行性能評估,量化指標總是必要的,那么如何量化呢?

這就需要我們的主角 JMH 登場了!

先給你們看個效果圖

性能對比圖

什么是JMH

JMH(Java Microbenchmark Harness)是用于代碼微基準測試的工具套件,主要是基于方法層面的基準測試,精度可以達到納秒級。

該工具是由 Oracle 內部實現 JIT 的大牛們編寫的,他們應該比任何人都了解 JIT 以及 JVM 對于基準測試的影響。

當你定位到熱點方法,希望進一步優化方法性能的時候,就可以使用 JMH 對優化的結果進行量化的分析。

JMH 比較典型的應用場景如下:

  • 想準確地知道某個方法需要執行多長時間,以及執行時間和輸入之間的相關性
  • 對比接口不同實現在給定條件下的吞吐量
  • 查看多少百分比的請求在多長時間內完成

下面我們以mongodb、hibernate、jdbc數據加載性能對比為例,使用 JMH 做基準測試。

怎么做JMH基準測試?

  • 加入依賴

因為 JMH 是 JDK9 自帶的,如果是 JDK9 之前的版本需要加入如下依賴:

  1. <dependency> 
  2.     <groupId>org.openjdk.jmh</groupId> 
  3.     <artifactId>jmh-core</artifactId> 
  4.     <version>1.29</version> 
  5. </dependency> 
  6. <dependency> 
  7.     <groupId>org.openjdk.jmh</groupId> 
  8.     <artifactId>jmh-generator-annprocess</artifactId> 
  9.     <version>1.29</version> 
  10. </dependency> 
  • 編寫基準測試

接下來,創建一個 JMH 測試類,具體代碼如下所示:

  1. @BenchmarkMode({Mode.AverageTime}) 
  2. @Warmup(iterations = 1, time = 5) 
  3. @Measurement(iterations = 3, time = 5) 
  4. @Threads(1) 
  5. @Fork(1) 
  6. @OutputTimeUnit(TimeUnit.MILLISECONDS) 
  7. @State(Scope.Benchmark) 
  8. public class ReadBenchMarks { 
  9.     @Benchmark 
  10.     public void loadMongoTemplate(){ 
  11.         // mongoTemplate數據加載 
  12.     } 
  13.  
  14.     @Benchmark 
  15.     public void loadMongoDriver(){ 
  16.         // mongoDriver數據加載 
  17.     } 
  18.  
  19.     @Benchmark 
  20.     public void loadHibernate(){ 
  21.         // hibernate數據加載 
  22.     } 
  23.  
  24.     @Benchmark 
  25.     public void loadJdbc(){ 
  26.         // jdbc數據加載 
  27.     } 
  28.  
  29.     public static void main(String[] args) throws RunnerException { 
  30.         Options options = new OptionsBuilder() 
  31.                 .include(ReadBenchMarks.class.getSimpleName()) 
  32.                 .output("db.log"
  33.                 .build(); 
  34.         new Runner(options).run(); 
  35.     } 

「核心關注點:」

類上加了注解

  • 需要測試的方法用 @Benchmark 注解標識
  • 啟動的方式

這些注解的具體含義將在下面介紹。

大家有興趣可以看下官方提供的 jmh 示例 demo:http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/

  • 執行基準測試

準備工作做好了,接下來,運行代碼,等待片刻,測試結果就出來了

  1. # JMH version: 1.29 
  2. # VM version: JDK 1.8.0_251, Java HotSpot(TM) Client VM, 25.251-b08 
  3. # VM invoker: C:\soft\Java\jdk1.8.0_251\jre\bin\java.exe 
  4. # VM options: -javaagent:C:\soft\idea\IntelliJ IDEA Community Edition 2020.1.1\lib\idea_rt.jar=53895:C:\soft\idea\IntelliJ IDEA Community Edition 2020.1.1\bin -Dfile.encoding=UTF-8 
  5. # Blackhole mode: full + dont-inline hint 
  6. # Warmup: 2 iterations, 5 s each 
  7. # Measurement: 10 iterations, 5 s each 
  8. # Timeout: 10 min per iteration 
  9. # Threads: 1 thread, will synchronize iterations 
  10. # Benchmark mode: Average timetime/op 
  11. # Benchmark: com.db.jmh.write.WriteBenchMarks.writeHibernate 
  12. # Parameters: (info = 10031,1,5) 
  13.  
  14. # Run progress: 0.00% complete, ETA 00:06:00 
  15. # Fork: 1 of 1 
  16. # Warmup Iteration   1: 7.743 ms/op 
  17. # Warmup Iteration   2: 9.433 ms/op 
  18. Iteration   1: 7.854 ms/op 
  19. Iteration   2: 8.638 ms/op 
  20. Iteration   3: 8.579 ms/op 
  21. Iteration   4: 8.213 ms/op 
  22. Iteration   5: 8.843 ms/op 
  23. Iteration   6: 9.178 ms/op 
  24. Iteration   7: 7.739 ms/op 
  25. Iteration   8: 9.608 ms/op 
  26. Iteration   9: 10.152 ms/op 
  27. Iteration  10: 9.461 ms/op 
  28.  
  29. Result "com.db.jmh.write.WriteBenchMarks.writeHibernate"
  30.   8.827 ±(99.9%) 1.182 ms/op [Average] 
  31.   (minavgmax) = (7.739, 8.827, 10.152), stdev = 0.782 
  32.   CI (99.9%): [7.645, 10.008] (assumes normal distribution) 
  33.  
  34. # Run complete. Total time: 00:06:38 
  35.  
  36. REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on 
  37. why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial 
  38. experiments, perform baseline and negative tests that provide experimental control, make sure 
  39. the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. 
  40. Do not assume the numbers tell you what you want them to tell. 
  41.  
  42. Benchmark                           (info)  Mode  Cnt   Score   Error  Units 
  43. WriteBenchMarks.writeHibernate   10031,1,5  avgt   10   8.827 ± 1.182  ms/op 
  44. WriteBenchMarks.writeHibernate   10032,5,6  avgt   10   8.783 ± 1.478  ms/op 
  45. WriteBenchMarks.writeHibernate  10033,5,20  avgt   10  12.574 ± 0.928  ms/op 
  46. WriteBenchMarks.writeMongo       10031,1,5  avgt   10   5.057 ± 0.358  ms/op 
  47. WriteBenchMarks.writeMongo       10032,5,6  avgt   10   7.392 ± 0.651  ms/op 
  48. WriteBenchMarks.writeMongo      10033,5,20  avgt   10  12.590 ± 0.795  ms/op 

下面對結果做下簡單說明:

  1. # JMH version: 1.29 
  2. # VM version: JDK 1.8.0_251, Java HotSpot(TM) Client VM, 25.251-b08 
  3. # VM invoker: C:\soft\Java\jdk1.8.0_251\jre\bin\java.exe 
  4. # VM options: -javaagent:C:\soft\idea\IntelliJ IDEA Community Edition 2020.1.1\lib\idea_rt.jar=53895:C:\soft\idea\IntelliJ IDEA Community Edition 2020.1.1\bin -Dfile.encoding=UTF-8 
  5. # Blackhole mode: full + dont-inline hint 
  6. # Warmup: 2 iterations, 5 s each 
  7. # Measurement: 10 iterations, 5 s each 
  8. # Timeout: 10 min per iteration 
  9. # Threads: 1 thread, will synchronize iterations 
  10. # Benchmark mode: Average timetime/op 
  11. # Benchmark: com.db.jmh.write.WriteBenchMarks.writeHibernate 
  12. # Parameters: (info = 10031,1,5) 

該部分為「測試的基本信息」,比如使用的 Java 路徑,預熱代碼的迭代次數,測量代碼的迭代次數,使用的線程數量,測試的統計單位等。

  1. # Warmup Iteration   1: 7.743 ms/op 
  2. # Warmup Iteration   2: 9.433 ms/op 

該部分為每一次熱身中的性能指標,預熱測試不會作為最終的統計結果。預熱的目的是「讓 JVM 對被測代碼進行足夠多的優化」,比如,在預熱后,被測代碼應該得到了充分的 JIT 編譯和優化。

  1. Iteration   1: 7.854 ms/op 
  2. Iteration   2: 8.638 ms/op 
  3. Iteration   3: 8.579 ms/op 
  4. Iteration   4: 8.213 ms/op 
  5. Iteration   5: 8.843 ms/op 
  6. Iteration   6: 9.178 ms/op 
  7. Iteration   7: 7.739 ms/op 
  8. Iteration   8: 9.608 ms/op 
  9. Iteration   9: 10.152 ms/op 
  10. Iteration  10: 9.461 ms/op 
  11.  
  12.  
  13. Result "com.db.jmh.write.WriteBenchMarks.writeHibernate"
  14.   8.827 ±(99.9%) 1.182 ms/op [Average] 
  15.   (minavgmax) = (7.739, 8.827, 10.152), stdev = 0.782 
  16.   CI (99.9%): [7.645, 10.008] (assumes normal distribution) 

該部分顯示測量迭代的情況,每一次迭代都顯示了當前的執行速率,即一個操作所花費的時,在進行 10 次迭代后,進行統計。

最后的測試結果如下所示:

  1. Benchmark                           (info)  Mode  Cnt   Score   Error  Units 
  2. WriteBenchMarks.writeHibernate   10031,1,5  avgt   10   8.827 ± 1.182  ms/op 
  3. WriteBenchMarks.writeHibernate   10032,5,6  avgt   10   8.783 ± 1.478  ms/op 
  4. WriteBenchMarks.writeHibernate  10033,5,20  avgt   10  12.574 ± 0.928  ms/op 
  5. WriteBenchMarks.writeMongo       10031,1,5  avgt   10   5.057 ± 0.358  ms/op 
  6. WriteBenchMarks.writeMongo       10032,5,6  avgt   10   7.392 ± 0.651  ms/op 
  7. WriteBenchMarks.writeMongo      10033,5,20  avgt   10  12.590 ± 0.795  ms/op 

看這些數據也能看出個大概,不過我不大可能直接將這個數據扔給老大, 因此用了以下兩個網站

  • JMH Visual Chart:http://deepoove.com/jmh-visual-chart/
  • JMH Visualizer:https://jmh.morethan.io/

生成了一開始看到的那張圖形化界面。

補充下,JMH 基礎

為了能夠更好地使用 JMH 的各項功能,下面對 JMH 的基本概念進行講解:

  • @BenchmarkMode

用來配置 Mode 選項,可用于類或者方法上,這個注解的 value 是一個數組,可以把幾種 Mode 集合在一起執行,如:@BenchmarkMode({Mode.SampleTime, Mode.AverageTime}),還可以設置為 Mode.All,即全部執行一遍。

  1. Throughput:整體吞吐量,每秒執行了多少次調用,單位為 ops/time
  2. AverageTime:用的平均時間,每次操作的平均時間,單位為 time/op
  3. SampleTime:隨機取樣,最后輸出取樣結果的分布
  4. SingleShotTime:只運行一次,往往同時把 Warmup 次數設為 0,用于測試冷啟動時的性能
  5. All:上面的所有模式都執行一次
  • @State

通過 State 可以指定一個對象的作用范圍,JMH 根據 scope 來進行實例化和共享操作。@State 可以被繼承使用,如果父類定義了該注解,子類則無需定義。由于 JMH 允許多線程同時執行測試,不同的選項含義如下:

  1. Scope.Benchmark:所有測試線程共享一個實例,測試有狀態實例在多線程共享下的性能
  2. Scope.Group:同一個線程在同一個 group 里共享實例
  3. Scope.Thread:默認的 State,每個測試線程分配一個實例

@OutputTimeUnit

為統計結果的時間單位,可用于類或者方法注解

  • @Warmup

預熱所需要配置的一些基本測試參數,可用于類或者方法上。一般前幾次進行程序測試的時候都會比較慢,所以要讓程序進行幾輪預熱,保證測試的準確性。參數如下所示:

  1. iterations:預熱的次數
  2. time:每次預熱的時間
  3. timeUnit:時間的單位,默認秒
  4. batchSize:批處理大小,每次操作調用幾次方法
  • @Measurement

實際調用方法所需要配置的一些基本測試參數,可用于類或者方法上,參數和 @Warmup 相同。

  • @Threads

每個進程中的測試線程,可用于類或者方法上。

  • @Fork

進行 fork 的次數,可用于類或者方法上。如果 fork 數是 2 的話,則 JMH 會 fork 出兩個進程來進行測試。

  • @Param

指定某項參數的多種情況,特別適合用來測試一個函數在不同的參數輸入的情況下的性能,只能作用在字段上,使用該注解必須定義 @State 注解。

在介紹完常用的注解后,讓我們來看下 JMH 有哪些陷阱。

回答個疑問,為什么需要預熱?

因為 JVM 的 JIT 機制的存在,如果某個函數被調用多次之后,JVM 會嘗試將其編譯為機器碼,從而提高執行速度,所以為了讓 benchmark 的結果更加接近真實情況就需要進行預熱。

如何將測試結果 可視化

其實很簡單,將main函數改成

  1. public static void main(String[] args) throws RunnerException { 
  2.     Options opt = new OptionsBuilder() 
  3.             .include(WriteBenchMarks.class.getSimpleName()) 
  4.             .result("db_read.json"
  5.             .resultFormat(ResultFormatType.JSON).build(); 
  6.     new Runner(opt).run(); 

就可以了,再將生成的json格式文件扔進以下網站:

  • JMH Visual Chart:http://deepoove.com/jmh-visual-chart/
  • JMH Visualizer:https://jmh.morethan.io/

就可以了啦。

「小飯飯:」 我測完啦,還生成了柱形圖給你看看

「主管小肥肥:」 不錯,mongodb的性能確實ok,你做的也不錯,還以為你會用System.currentTimeMillis()這種low的手段呢,沒想到用上了JMH,做的不錯,快調薪了,必須給你加一筆。

原文鏈接:https://mp.weixin.qq.com/s/hTRa-eOSvSns0sm2P2BMVg

 

責任編輯:武曉燕 來源: 稀飯下雪
相關推薦

2023-10-20 11:24:25

JMH基準測試

2021-12-29 10:30:15

JMH代碼Java

2016-09-23 16:36:25

LinuxPCPhoronix

2023-07-31 09:13:13

ValidatorGolang

2024-03-06 18:09:06

Linux性能工具

2021-07-17 15:25:05

PHP 8.1基準測試開發

2009-10-10 11:11:40

服務器測試

2013-05-07 09:47:30

測試MySQLMySQL測試

2012-07-31 09:02:49

Apworks

2023-01-06 08:31:53

數據庫基準測試

2011-09-27 10:11:14

MongoDBR

2011-03-03 10:32:07

Mongodb億級數據量

2022-03-29 11:48:40

Go泛型測試

2023-05-12 13:21:12

JMHJava程序

2023-10-08 16:28:36

數據庫DuckDB

2010-05-13 15:43:34

MySQL宣布

2015-05-19 16:52:13

企業網D1Net

2020-06-10 10:40:03

JavaJMH字符串

2022-07-06 09:29:40

JMH性能測試

2009-02-09 11:06:19

WindowsUbuntuWindows7
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九一视频在线观看 | 日本精品网站 | 天天精品在线 | 国产成人精品视频在线观看 | 欧美日韩中文在线 | 男女搞网站 | 成在线人视频免费视频 | 久草视频在线播放 | 成人深夜福利在线观看 | 亚洲欧美精品在线观看 | 中文字幕一区在线观看视频 | 亚洲一区精品在线 | 国产在线1区 | 国产一区二区三区久久久久久久久 | 日韩久久网| 超碰免费在线观看 | 欧美国产精品一区二区三区 | 国产精品亚洲一区二区三区在线 | 99精品在线免费观看 | 视频一区二区三区四区五区 | 亚洲www| 91日韩 | 九九久久99 | 国产福利网站 | 亚洲视频中文字幕 | 亚洲精品乱码久久久久久9色 | 国产传媒毛片精品视频第一次 | 成人午夜精品一区二区三区 | 午夜视频网站 | 久久久www成人免费无遮挡大片 | 五月天激情电影 | 色视频网站在线观看 | 中文字幕视频在线 | 欧美一级片久久 | www在线视频 | 久久精品男人的天堂 | 日韩一区二区三区在线观看 | 伊人天堂网 | 日韩影院一区 | 国产精品久久毛片av大全日韩 | 成年人国产在线观看 |