簡體   English   中英

我如何在 Java 中對方法執行時間進行基准測試?

[英]How can i benchmark method execution time in java?

我有一個我自己用 java 編寫的程序,但我想測試方法執行時間並獲取特定方法的時間。 我想知道這是否可能,也許是一個 eclipse 插件? 或者插入一些代碼?

我明白了,它是一個很小的程序,不超過 1500 行,哪個更好用專用工具或System.currentTimeMillis()

除了使用分析器之外,獲得所需內容的簡單方法如下:

public class SomeClass{
   public void somePublicMethod()
   {
       long startTime = System.currentTimeMillis();
       someMethodWhichYouWantToProfile();
       long endTime = System.currentTimeMillis();
       System.out.println("Total execution time: " + (endTime-startTime) + "ms"); 
   }
 }

如果瓶頸大到可以用探查器觀察到,請使用探查器。

如果您需要更高的准確性,衡量一小段代碼的最佳方法是使用 Java 微基准測試框架,例如OpenJDK 的 JMHGoogle 的 Caliper 我相信它們與 JUnit 一樣易於使用,不僅您將獲得更准確的結果,而且您​​將從社區獲得專業知識以正確執行此操作。

遵循 JMH 微基准測試來測量Math.log()的執行時間:

private double x = Math.PI;

@Benchmark
public void myBenchmark() {
    return Math.log(x)
}

使用currentMillis()nanoTime()進行測量有很多限制:

  1. 它們有延遲(它們也需要時間來執行),這會影響您的測量。
  2. 它們的精度非常有限,這意味着您可以測量 linux 中 26ns 到 26ns 和 Windows 中 300 左右的內容,已在此處描述
  3. 不考慮預熱階段,使您的測量值波動很大。

currentMillis()nanoTime()在Java方法可能是有用的,但必須慎用或你可以得到錯誤的測量結果的誤差像這樣被測量的片段的順序影響測量或像這樣在這里筆者錯誤地得出結論,幾個在不到一毫秒的時間內執行了數百萬次操作,而實際上 JMV 沒有實現任何操作並提升代碼,根本不運行任何代碼。

這是一個精彩的視頻,解釋了如何以正確的方式進行微基准測試: https : //shipilev.net/#benchmarking

對於快速和骯臟的時間測量測試,不要使用掛鍾時間( System.currentTimeMillis() )。 更喜歡System.nanoTime()

public static void main(String... ignored) throws InterruptedException {
    final long then = System.nanoTime();
    TimeUnit.SECONDS.sleep(1);
    final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - then);
    System.out.println("Slept for (ms): " + millis); // = something around 1000.
}

您應該使用類似的分析器

它們將輕松與任何 IDE 集成並顯示您需要的任何細節。

當然,這些工具很復雜,旨在用於分析復雜的程序,如果您只需要一些簡單的基准測試,我建議您使用System.currentTimeMillis()System.nanoTime()System.nanoTime()計算調用之間的毫秒增量。

使用分析器更好,因為您可以找出應用程序中的平均執行時間和瓶頸。

我使用VisualVM 圓滑而簡單。

Google Guava 有一個秒表,讓事情變得簡單易行。

Stopwatch stopwatch = Stopwatch.createStarted();
myFunctionCall();
LOGGER.debug("Time taken by myFunctionCall: " + stopwatch.stop());

Jprofiler 和 yourkit 都不錯,但要花錢。

eclispe 有一個免費插件,稱為 TPTP(測試和性能工具平台),它可以為您提供代碼執行時間。 這是一個快速谷歌搜索帶來的教程。 http://www.eclipse.org/articles/Article-TPTP-Profiling-Tool/tptpProfilingArticle.html

另一個定制的解決方案可以基於以下帖子: http : //www.mkyong.com/spring/spring-aop-examples-advice/

然后,您還可以使用有關應用程序監控和 snmp 的實用程序。 如果您需要在生產環境中定期“計時”您的方法,您可能應該考慮使用這些 SNMP 工具之一

您可以添加此代碼,它會告訴您該方法執行所需的時間。

long millisecondsStart = System.currentTimeMillis();
executeMethod();
long timeSpentInMilliseconds = System.currentTimeMillis() - millisecondsStart;

通常我將時間存儲在 .txt 文件中以分析結果

StopWatch sWatch = new StopWatch();
sWatch.start();

//do stuff that you want to measure
downloadContent();

sWatch.stop();

//make the time pretty
long timeInMilliseconds = sWatch.getTime();
long hours = TimeUnit.MILLISECONDS.toHours(timeInMilliseconds);
long minutes = TimeUnit.MILLISECONDS.toMinutes(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours));
long seconds = TimeUnit.MILLISECONDS.toSeconds(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours) - TimeUnit.MINUTES.toMillis(minutes));
long milliseconds = timeInMilliseconds - TimeUnit.HOURS.toMillis(hours) - TimeUnit.MINUTES.toMillis(minutes) - TimeUnit.SECONDS.toMillis(seconds);

String t = String.format("%02d:%02d:%02d:%d", hours, minutes, seconds, milliseconds);

//each line to store in a txt file, new line
String content = "Ref: " + ref + "  -  " + t + "\r\n";

//you may want wrap this section with a try catch
File file = new File("C:\\time_log.txt");
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true); //append content set to true, so it does not overwrite existing data
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM