繁体   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