
Java 教程
- Java - 首頁
- Java - 概述
- Java - 歷史
- Java - 特性
- Java 與 C++
- JVM - Java 虛擬機器
- Java - JDK 與 JRE 與 JVM
- Java - Hello World 程式
- Java - 環境設定
- Java - 基本語法
- Java - 變數型別
- Java - 資料型別
- Java - 型別轉換
- Java - Unicode 系統
- Java - 基本運算子
- Java - 註釋
- Java - 使用者輸入
- Java - 日期和時間
Java 控制語句
- Java - 迴圈控制
- Java - 決策制定
- Java - If-else
- Java - Switch
- Java - For 迴圈
- Java - For-Each 迴圈
- Java - While 迴圈
- Java - do-while 迴圈
- Java - Break
- Java - Continue
面向物件程式設計
- Java - OOPs 概念
- Java - 物件和類
- Java - 類屬性
- Java - 類方法
- Java - 方法
- Java - 變數作用域
- Java - 建構函式
- Java - 訪問修飾符
- Java - 繼承
- Java - 聚合
- Java - 多型
- Java - 重寫
- Java - 方法過載
- Java - 動態繫結
- Java - 靜態繫結
- Java - 例項初始化塊
- Java - 抽象
- Java - 封裝
- Java - 介面
- Java - 包
- Java - 內部類
- Java - 靜態類
- Java - 匿名類
- Java - 單例類
- Java - 包裝類
- Java - 列舉
- Java - 列舉建構函式
- Java - 列舉字串
Java 內建類
Java 檔案處理
Java 錯誤和異常
- Java - 異常
- Java - try-catch 塊
- Java - try-with-resources
- Java - 多重 catch 塊
- Java - 巢狀 try 塊
- Java - Finally 塊
- Java - throw 異常
- Java - 異常傳播
- Java - 內建異常
- Java - 自定義異常
Java 多執行緒
- Java - 多執行緒
- Java - 執行緒生命週期
- Java - 建立執行緒
- Java - 啟動執行緒
- Java - 執行緒連線
- Java - 執行緒命名
- Java - 執行緒排程器
- Java - 執行緒池
- Java - 主執行緒
- Java - 執行緒優先順序
- Java - 守護執行緒
- Java - 執行緒組
- Java - 關閉鉤子
Java 同步
Java 網路
- Java - 網路
- Java - 套接字程式設計
- Java - URL 處理
- Java - URL 類
- Java - URLConnection 類
- Java - HttpURLConnection 類
- Java - Socket 類
- Java - 泛型
Java 集合
Java 介面
Java 資料結構
Java 集合演算法
高階 Java
- Java - 命令列引數
- Java - Lambda 表示式
- Java - 傳送郵件
- Java - Applet 基礎
- Java - Javadoc 註釋
- Java - 自動裝箱和拆箱
- Java - 檔案不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 檔案
- Java - 私有介面方法
- Java - 內部類菱形運算子
- Java - 多解析度影像 API
- Java - 集合工廠方法
- Java - 模組系統
- Java - Nashorn JavaScript
- Java - Optional 類
- Java - 方法引用
- Java - 函式式介面
- Java - 預設方法
- Java - Base64 編碼解碼
- Java - Switch 表示式
- Java - Teeing 收集器
- Java - 微基準測試
- Java - 文字塊
- Java - 動態 CDS 歸檔
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指標異常
- Java - 打包工具
- Java - 密封類
- Java - 記錄類
- Java - 隱藏類
- Java - 模式匹配
- Java - 簡潔數字格式化
- Java - 垃圾回收
- Java - JIT 編譯器
Java 雜項
- Java - 遞迴
- Java - 正則表示式
- Java - 序列化
- Java - 字串
- Java - Process API 改進
- Java - Stream API 改進
- Java - 增強的 @Deprecated 註釋
- Java - CompletableFuture API 改進
- Java - 流
- Java - 日期時間 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 和框架
Java 類參考
- Java - Scanner
- Java - 陣列
- Java - 字串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用資源
Java - 微基準測試
Java 基準測試
基準測試是一種檢查應用程式或應用程式程式碼部分效能的技術,以吞吐量、平均花費時間等為指標。在Java 基準測試中,我們檢查應用程式程式碼或正在使用的庫的效能。此基準測試有助於在遇到大量負載時識別程式碼中的任何瓶頸,或識別應用程式效能下降的情況。
Java 基準測試的重要性
應用程式效能是任何應用程式的一個非常重要的屬性。編寫不當的程式碼會導致應用程式無響應,以及高記憶體使用率,這可能導致糟糕的使用者體驗,甚至使應用程式無法使用。為了解決此類問題,對應用程式進行基準測試至關重要。
Java 開發人員應該能夠找到應用程式中的問題並使用基準測試技術修復它們,這可以幫助識別緩慢的程式碼。
Java 基準測試技術
開發人員為了基準測試應用程式程式碼、系統、庫或任何元件,部署了多種技術。以下是其中一些重要技術。
使用開始/結束時間進行基準測試
此技術易於使用,並且適用於一小段程式碼,我們可以在呼叫程式碼之前以納秒為單位獲取開始時間,然後在執行方法後,我們再次獲取時間。現在,使用結束時間和開始時間的差值可以瞭解程式碼花費了多少時間。此技術很簡單,但不可靠,因為效能會因許多因素而異,例如正在執行的垃圾收集器以及在此期間執行的任何系統程序。
// get the start time long startTime = System.nanoTime(); // execute the code to be benchmarked long result = operations.timeTakingProcess(); // get the end time long endTime = System.nanoTime(); // compute the time taken long timeElapsed = endTime - startTime;
示例
以下示例顯示了一個執行示例,以演示上述概念。
package com.tutorialspoint; public class Operations { public static void main(String[] args) { Operations operations = new Operations(); // get the start time long startTime = System.nanoTime(); // execute the code to be benchmarked long result = operations.timeTakingProcess(); // get the end time long endTime = System.nanoTime(); // compute the time taken long timeElapsed = endTime - startTime; System.out.println("Sum of 100,00 natural numbers: " + result); System.out.println("Elapsed time: " + timeElapsed + " nanoseconds"); } // get the sum of first 100,000 natural numbers public long timeTakingProcess() { long sum = 0; for(int i = 0; i < 100000; i++ ) { sum += i; } return sum; } }
讓我們編譯並執行上述程式,這將產生以下結果 -
Sum of 100,00 natural numbers: 4999950000 Elapsed time: 1111300 nanoseconds
使用 Java 微基準測試工具 (JMH) 進行基準測試
Java 微基準測試工具 (JMH) 是由 OpenJDK 社群開發的一個功能強大的基準測試 API,用於檢查程式碼的效能。它提供了一種簡單的基於註釋的方法來獲取方法/類的基準資料,開發人員只需編寫很少的程式碼。
步驟 1 - 註釋要進行基準測試的類/方法。
@Benchmark public long timeTakingProcess() { }
步驟 2 - 準備基準測試選項,並使用基準測試執行器執行。
// prepare the options Options options = new OptionsBuilder() .include(Operations.class.getSimpleName()) // use the class whose method is to be benchmarked .forks(1) // create the fork(s) which will be used to run the iterations .build(); // run the benchmark runner new Runner(options).run();
為了使用基準測試庫,我們需要在 Maven 專案的 pom.xml 中新增以下依賴項。
<dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>1.35</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>1.35</version> </dependency>
以下是用於執行上述基準測試示例的 pom.xml 的完整程式碼。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint</groupId> <artifactId>test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>test</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jmh.version>1.35</jmh.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>${jmh.version}</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>17</source> <target>17</target> <annotationProcessorPaths> <path> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>benchmarks</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.openjdk.jmh.Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
示例
以下是用於執行上述基準測試示例的類的完整程式碼。
package com.tutorialspoint.test; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; public class Operations { public static void main(String[] args) throws RunnerException { Options options = new OptionsBuilder() .include(Operations.class.getSimpleName()) .forks(1) .build(); new Runner(options).run(); } // get the sum of first 100,000 natural numbers @Benchmark public long timeTakingProcess() { long sum = 0; for(int i = 0; i < 100000; i++ ) { sum += i; } return sum; } }
讓我們編譯並執行上述程式,這將產生以下結果 -
# JMH version: 1.35 # VM version: JDK 21.0.2, Java HotSpot(TM) 64-Bit Server VM, 21.0.2+13-LTS-58 # VM invoker: C:\Program Files\Java\jdk-21\bin\java.exe # VM options: -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ShowCodeDetailsInExceptionMessages # Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) # Warmup: 5 iterations, 10 s each # Measurement: 5 iterations, 10 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: com.tutorialspoint.test.Operations.timeTakingProcess # Run progress: 0.00% complete, ETA 00:01:40 # Fork: 1 of 1 # Warmup Iteration 1: 33922.775 ops/s # Warmup Iteration 2: 34104.930 ops/s # Warmup Iteration 3: 34519.419 ops/s # Warmup Iteration 4: 34535.636 ops/s # Warmup Iteration 5: 34508.781 ops/s Iteration 1: 34497.252 ops/s Iteration 2: 34338.847 ops/s Iteration 3: 34355.355 ops/s Iteration 4: 34105.801 ops/s Iteration 5: 34104.127 ops/s Result "com.tutorialspoint.test.Operations.timeTakingProcess": 34280.276 ±(99.9%) 660.293 ops/s [Average] (min, avg, max) = (34104.127, 34280.276, 34497.252), stdev = 171.476 CI (99.9%): [33619.984, 34940.569] (assumes normal distribution) # Run complete. Total time: 00:01:40 REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial experiments, perform baseline and negative tests that provide experimental control, make sure the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. Do not assume the numbers tell you what you want them to tell. NOTE: Current JVM experimentally supports Compiler Blackholes, and they are in use. Please exercise extra caution when trusting the results, look into the generated code to check the benchmark still works, and factor in a small probability of new VM bugs. Additionally, while comparisons between different JVMs are already problematic, the performance difference caused by different Blackhole modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons. Benchmark Mode Cnt Score Error Units Operations.timeTakingProcess thrpt 5 34280.276 ± 660.293 ops/s