956
  1. 如何获取方法的执行时间?
  2. 是否有一个Timer实用程序类用于计时任务需要多长时间等?

Google 上的大多数搜索都会返回调度线程和任务的计时器的结果,这不是我想要的。

4

42 回答 42

1373

总是有老式的方法:

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.
于 2008-10-07T20:16:16.373 回答
240

我选择简单的答案。为我工作。

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

它工作得很好。分辨率显然只有毫秒,使用 System.nanoTime() 可以做得更好。两者都有一些限制(操作系统调度切片等),但这工作得很好。

几次运行的平均值(越多越好),你会得到一个不错的主意。

于 2008-10-07T20:14:29.560 回答
194

拜托了伙计们!没有人提到Guava的方法(可以说是很棒的):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

好消息是 Stopwatch.toString() 在为测量选择时间单位方面做得很好。即数值小则输出38ns,长则显示5m 3s

更好的是:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

注意:Google Guava 需要 Java 1.6+

于 2013-03-13T20:11:24.663 回答
165

使用Java 8 新 API 中的InstantDuration ,

Instant start = Instant.now();
Thread.sleep(5000);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

输出,

PT5S
于 2015-02-02T09:19:33.953 回答
137

将所有可能的方式聚集到一个地方。

日期

Date startDate = Calendar.getInstance().getTime();
long d_StartTime = new Date().getTime();
Thread.sleep(1000 * 4);
Date endDate = Calendar.getInstance().getTime();
long d_endTime = new Date().getTime();
System.out.format("StartDate : %s, EndDate : %s \n", startDate, endDate);
System.out.format("Milli = %s, ( D_Start : %s, D_End : %s ) \n", (d_endTime - d_StartTime),d_StartTime, d_endTime);

系统。当前时间米利斯()

long startTime = System.currentTimeMillis();
Thread.sleep(1000 * 4);
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);  
System.out.format("Milli = %s, ( S_Start : %s, S_End : %s ) \n", duration, startTime, endTime );
System.out.println("Human-Readable format : "+millisToShortDHMS( duration ) );

人类可读格式

public static String millisToShortDHMS(long duration) {
    String res = "";    // java.util.concurrent.TimeUnit;
    long days       = TimeUnit.MILLISECONDS.toDays(duration);
    long hours      = TimeUnit.MILLISECONDS.toHours(duration) -
                      TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes    = TimeUnit.MILLISECONDS.toMinutes(duration) -
                      TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds    = TimeUnit.MILLISECONDS.toSeconds(duration) -
                      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    long millis     = TimeUnit.MILLISECONDS.toMillis(duration) - 
                      TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));

    if (days == 0)      res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
    else                res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
    return res;
}

Guava: Google Stopwatch JAR « 秒表的一个对象是以纳秒为单位测量经过的时间。

com.google.common.base.Stopwatch g_SW = Stopwatch.createUnstarted();
g_SW.start();
Thread.sleep(1000 * 4);
g_SW.stop();
System.out.println("Google StopWatch  : "+g_SW);

Apache Commons Lang JAR « StopWatch为计时提供了方便的 API。

org.apache.commons.lang3.time.StopWatch sw = new StopWatch();
sw.start();     
Thread.sleep(1000 * 4);     
sw.stop();
System.out.println("Apache StopWatch  : "+ millisToShortDHMS(sw.getTime()) );

乔达时代

public static void jodaTime() throws InterruptedException, ParseException{
    java.text.SimpleDateFormat ms_SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    String start = ms_SDF.format( new Date() ); // java.util.Date

    Thread.sleep(10000);

    String end = ms_SDF.format( new Date() );       
    System.out.println("Start:"+start+"\t Stop:"+end);

    Date date_1 = ms_SDF.parse(start);
    Date date_2 = ms_SDF.parse(end);        
    Interval interval = new org.joda.time.Interval( date_1.getTime(), date_2.getTime() );
    Period period = interval.toPeriod(); //org.joda.time.Period

    System.out.format("%dY/%dM/%dD, %02d:%02d:%02d.%04d \n", 
        period.getYears(), period.getMonths(), period.getDays(),
        period.getHours(), period.getMinutes(), period.getSeconds(), period.getMillis());
}

Java 8 中的 Java 日期时间 API « Duration对象表示两个Instant对象之间的时间段。

Instant start = java.time.Instant.now();
    Thread.sleep(1000);
Instant end = java.time.Instant.now();
Duration between = java.time.Duration.between(start, end);
System.out.println( between ); // PT1.001S
System.out.format("%dD, %02d:%02d:%02d.%04d \n", between.toDays(),
        between.toHours(), between.toMinutes(), between.getSeconds(), between.toMillis()); // 0D, 00:00:01.1001 

Spring Framework提供了StopWatch实用程序类来测量 Java 中的经过时间。

StopWatch sw = new org.springframework.util.StopWatch();
sw.start("Method-1"); // Start a named task
    Thread.sleep(500);
sw.stop();

sw.start("Method-2");
    Thread.sleep(300);
sw.stop();

sw.start("Method-3");
    Thread.sleep(200);
sw.stop();

System.out.println("Total time in milliseconds for all tasks :\n"+sw.getTotalTimeMillis());
System.out.println("Table describing all tasks performed :\n"+sw.prettyPrint());

System.out.format("Time taken by the last task : [%s]:[%d]", 
        sw.getLastTaskName(),sw.getLastTaskTimeMillis());

System.out.println("\n Array of the data for tasks performed « Task Name: Time Taken");
TaskInfo[] listofTasks = sw.getTaskInfo();
for (TaskInfo task : listofTasks) {
    System.out.format("[%s]:[%d]\n", 
            task.getTaskName(), task.getTimeMillis());
}

输出:

Total time in milliseconds for all tasks :
999
Table describing all tasks performed :
StopWatch '': running time (millis) = 999
-----------------------------------------
ms     %     Task name
-----------------------------------------
00500  050%  Method-1
00299  030%  Method-2
00200  020%  Method-3

Time taken by the last task : [Method-3]:[200]
 Array of the data for tasks performed « Task Name: Time Taken
[Method-1]:[500]
[Method-2]:[299]
[Method-3]:[200]
于 2015-12-04T10:43:43.500 回答
90

使用分析器(JProfiler、Netbeans Profiler、Visual VM、Eclipse Profiler 等)。您将获得最准确的结果,并且干扰最少。他们使用内置的 JVM 机制进行分析,如果需要,还可以为您提供额外的信息,如堆栈跟踪、执行路径和更全面的结果。

当使用一个完全集成的分析器时,分析一个方法是非常简单的。右键单击,Profiler -> 添加到根方法。然后像进行测试运行或调试器一样运行分析器。

于 2008-10-07T21:35:58.927 回答
47

System.currentTimeMillis();不是衡量算法性能的好方法。它衡量您作为用户观看计算机屏幕所经历的总时间。它还包括在您的计算机上在后台运行的所有其他内容所消耗的时间。如果您的工作站上有很多程序正在运行,这可能会产生巨大的影响。

正确的方法是使用java.lang.management包。

来自http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking网站(存档链接):

  • “用户时间”是运行应用程序自己的代码所花费的时间。
  • “系统时间”是代表您的应用程序(例如 I/O)运行操作系统代码所花费的时间。

getCpuTime()方法给你这些总和:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}
于 2014-04-06T13:46:01.810 回答
43

这可能不是您要我说的,但这是 AOP 的一个很好的用途。在您的方法周围使用代理拦截器,并在那里进行计时。

遗憾的是,AOP 的内容、原因和方式超出了这个答案的范围,但我可能会这样做。

编辑:如果您愿意的话,这里有一个指向 Spring AOP 的链接,可以帮助您入门。这是 Iive 为 java 遇到的最容易访问的 AOP 实现。

另外,鉴于其他人的非常简单的建议,我应该补充一点,AOP 适用于您不希望诸如时间之类的东西侵入您的代码时。但在很多情况下,那种简单易行的方法就可以了。

于 2008-10-07T20:13:00.640 回答
34

使用 Java 8,您还可以对每个普通方法执行类似的操作:

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

与 TimeIt 一样:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

使用这种方法,您可以在代码中的任何位置轻松测量时间而不会破坏它。在这个简单的例子中,我只是打印时间。您可以为 TimeIt 添加一个 Switch,例如仅在 DebugMode 或其他方式下打印时间。

如果您正在使用Function,您可以执行以下操作:

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}
于 2015-11-25T22:47:42.793 回答
21

我们也可以使用 Apache commons 的 StopWatch 类来测量时间。

示例代码

org.apache.commons.lang.time.StopWatch sw = new org.apache.commons.lang.time.StopWatch();

System.out.println("getEventFilterTreeData :: Start Time : " + sw.getTime());
sw.start();

// Method execution code

sw.stop();
System.out.println("getEventFilterTreeData :: End Time : " + sw.getTime());
于 2011-12-03T04:37:24.460 回答
19

JEP 230:微基准套件

仅供参考,JEP 230:Microbenchmark Suite是一个OpenJDK项目,用于:

在 JDK 源代码中添加一套基本的微基准测试,让开发人员可以轻松运行现有的微基准测试并创建新的微基准测试。

此功能在Java 12中出现。

Java 微基准线束 (JMH)

对于 Java 的早期版本,请查看JEP 230 所基于的Java Microbenchmark Harness (JMH)项目。

于 2016-07-01T22:59:18.107 回答
15

只是一个小转折,如果您不使用工具并且想要对执行时间较短的方法进行计时:执行多次,每次执行次数加倍,直到达到一秒左右。因此,调用 System.nanoTime 等的时间,以及 System.nanoTime 的准确性对结果影响很大。

    int runs = 0, runsPerRound = 10;
    long begin = System.nanoTime(), end;
    do {
        for (int i=0; i<runsPerRound; ++i) timedMethod();
        end = System.nanoTime();
        runs += runsPerRound;
        runsPerRound *= 2;
    } while (runs < Integer.MAX_VALUE / 2 && 1000000000L > end - begin);
    System.out.println("Time for timedMethod() is " + 
        0.000000001 * (end-begin) / runs + " seconds");

当然,使用挂钟的注意事项适用:JIT 编译的影响、多线程/进程等。因此,您需要先执行该方法很多次,以便 JIT 编译器完成其工作,然后多次重复此测试并采用最短的执行时间。

于 2008-11-05T07:20:10.990 回答
14

为此,我们使用 AspectJ 和 Java 注释。如果我们需要知道某个方法的执行时间,我们只需对其进行注释即可。更高级的版本可以使用自己的日志级别,可以在运行时启用和禁用。

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}
于 2008-10-08T06:40:38.203 回答
11

真的很好的代码。

http://www.rgagnon.com/javadetails/java-0585.html

import java.util.concurrent.TimeUnit;

long startTime = System.currentTimeMillis();
........
........
........
long finishTime = System.currentTimeMillis();

String diff = millisToShortDHMS(finishTime - startTime);


  /**
   * converts time (in milliseconds) to human-readable format
   *  "<dd:>hh:mm:ss"
   */
  public static String millisToShortDHMS(long duration) {
    String res = "";
    long days  = TimeUnit.MILLISECONDS.toDays(duration);
    long hours = TimeUnit.MILLISECONDS.toHours(duration)
                   - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
                     - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
                   - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    if (days == 0) {
      res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    else {
      res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
    }
    return res;
  }
于 2012-06-15T08:50:47.273 回答
11

根据 JavaDoc,Spring 提供了一个实用程序类org.springframework.util.StopWatch :

简单的秒表,允许对多个任务进行计时,显示每个命名任务的总运行时间和运行时间。

用法:

StopWatch stopWatch = new StopWatch("Performance Test Result");

stopWatch.start("Method 1");
doSomething1();//method to test
stopWatch.stop();

stopWatch.start("Method 2");
doSomething2();//method to test
stopWatch.stop();

System.out.println(stopWatch.prettyPrint());

输出:

StopWatch 'Performance Test Result': running time (millis) = 12829
-----------------------------------------
ms     %     Task name
-----------------------------------------
11907  036%  Method 1
00922  064%  Method 2

方面:

@Around("execution(* my.package..*.*(..))")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Object retVal = joinPoint.proceed();
    stopWatch.stop();
    log.info(" execution time: " + stopWatch.getTotalTimeMillis() + " ms");
    return retVal;
}
于 2015-08-06T10:26:32.940 回答
10

您可以使用Perf4j。非常酷的实用程序。用法很简单

String watchTag = "target.SomeMethod";
StopWatch stopWatch = new LoggingStopWatch(watchTag);
Result result = null; // Result is a type of a return value of a method
try {
    result = target.SomeMethod();
    stopWatch.stop(watchTag + ".success");
} catch (Exception e) {
    stopWatch.stop(watchTag + ".fail", "Exception was " + e);
    throw e; 
}

更多信息可以在开发者指南中找到

编辑:项目似乎死了

于 2012-02-26T15:07:53.013 回答
10

我写了一个方法,以一种可读的形式打印方法执行时间。例如,要计算 100 万的阶乘,大约需要 9 分钟。所以执行时间打印为:

Execution Time: 9 Minutes, 36 Seconds, 237 MicroSeconds, 806193 NanoSeconds

代码在这里:

public class series
{
    public static void main(String[] args)
    {
        long startTime = System.nanoTime();

        long n = 10_00_000;
        printFactorial(n);

        long endTime = System.nanoTime();
        printExecutionTime(startTime, endTime);

    }

    public static void printExecutionTime(long startTime, long endTime)
    {
        long time_ns = endTime - startTime;
        long time_ms = TimeUnit.NANOSECONDS.toMillis(time_ns);
        long time_sec = TimeUnit.NANOSECONDS.toSeconds(time_ns);
        long time_min = TimeUnit.NANOSECONDS.toMinutes(time_ns);
        long time_hour = TimeUnit.NANOSECONDS.toHours(time_ns);

        System.out.print("\nExecution Time: ");
        if(time_hour > 0)
            System.out.print(time_hour + " Hours, ");
        if(time_min > 0)
            System.out.print(time_min % 60 + " Minutes, ");
        if(time_sec > 0)
            System.out.print(time_sec % 60 + " Seconds, ");
        if(time_ms > 0)
            System.out.print(time_ms % 1E+3 + " MicroSeconds, ");
        if(time_ns > 0)
            System.out.print(time_ns % 1E+6 + " NanoSeconds");
    }
}
于 2018-10-29T19:18:20.373 回答
8

使用来自jcabi-aspects 的AOP/AspectJ 和@Loggable注释,您可以轻松紧凑地完成它:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

对该方法的每次调用都将发送到具有DEBUG日志记录级别的 SLF4J 日志记录工具。每条日志消息都将包含执行时间。

于 2013-01-06T20:12:22.387 回答
8
new Timer(""){{
    // code to time 
}}.timeMe();



public class Timer {

    private final String timerName;
    private long started;

    public Timer(String timerName) {
        this.timerName = timerName;
        this.started = System.currentTimeMillis();
    }

    public void timeMe() {
        System.out.println(
        String.format("Execution of '%s' takes %dms.", 
                timerName, 
                started-System.currentTimeMillis()));
    }

}
于 2013-04-03T14:13:33.093 回答
7

我基本上做了这个的变体,但考虑到热点编译的工作原理,如果你想获得准确的结果,你需要放弃前几次测量,并确保你在现实世界(阅读特定于应用程序的)应用程序中使用该方法。

如果 JIT 决定编译它,您的数字将有很大差异。所以请注意

于 2008-10-07T20:17:47.837 回答
7

有几种方法可以做到这一点。我通常会退回到只使用这样的东西:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

或与 System.nanoTime() 相同的东西;

对于更多关于基准测试方面的内容,似乎也有这个:http: //jetm.void.fm/虽然从未尝试过。

于 2008-10-07T20:18:33.030 回答
7

您可以使用提供各种测量仪器的Metrics库。添加依赖:

<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>

并为您的环境配置它。

方法可以用@Timed注释:

@Timed
public void exampleMethod(){
    // some code
}

或用Timer包装的一段代码:

final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();

聚合指标可以导出到控制台、JMX、CSV 或其他。

@Timed指标输出示例:

com.example.ExampleService.exampleMethod
             count = 2
         mean rate = 3.11 calls/minute
     1-minute rate = 0.96 calls/minute
     5-minute rate = 0.20 calls/minute
    15-minute rate = 0.07 calls/minute
               min = 17.01 milliseconds
               max = 1006.68 milliseconds
              mean = 511.84 milliseconds
            stddev = 699.80 milliseconds
            median = 511.84 milliseconds
              75% <= 1006.68 milliseconds
              95% <= 1006.68 milliseconds
              98% <= 1006.68 milliseconds
              99% <= 1006.68 milliseconds
            99.9% <= 1006.68 milliseconds
于 2017-07-31T10:53:13.923 回答
6

如果你想要挂钟时间

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;
于 2008-10-07T20:14:38.670 回答
6

在 Spring 框架中,我们有一个名为 StopWatch (org.springframework.util.StopWatch) 的调用

//measuring elapsed time using Spring StopWatch
        StopWatch watch = new StopWatch();
        watch.start();
        for(int i=0; i< 1000; i++){
            Object obj = new Object();
        }
        watch.stop();
        System.out.println("Total execution time to create 1000 objects in Java using StopWatch in millis: "
                + watch.getTotalTimeMillis());
于 2020-05-16T05:04:26.310 回答
5
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds
于 2008-10-07T20:16:25.360 回答
5

正如“skaffman”所说,使用 AOP 或者您可以使用运行时字节码编织,就像单元测试方法覆盖工具用于透明地将时间信息添加到调用的方法一样。

您可以查看 Emma 等开源工具工具使用的代码 ( http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0 )。另一个开源覆盖工具是http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download

如果你最终设法做你所设定的,请。与您的 ant 任务/jars 在这里与社区分享。

于 2008-10-07T20:21:19.047 回答
4

我修改了正确答案的代码以在几秒钟内得到结果:

long startTime = System.nanoTime();

methodCode ...

long endTime = System.nanoTime();
double duration = (double)(endTime - startTime) / (Math.pow(10, 9));
Log.v(TAG, "MethodName time (s) = " + duration);
于 2013-12-27T15:18:50.590 回答
4

我机器上的性能测量

  • System.nanoTime() : 750ns
  • System.currentTimeMillis() : 18ns

如前所述,System.nanoTime()被认为可以测量经过的时间。如果在循环等内部使用,请注意成本。

于 2014-09-17T07:04:28.007 回答
4

好的,这是一个简单的类,用于对您的函数进行简单的简单计时。下面有一个例子。

public class Stopwatch {
    static long startTime;
    static long splitTime;
    static long endTime;

    public Stopwatch() {
        start();
    }

    public void start() {
        startTime = System.currentTimeMillis();
        splitTime = System.currentTimeMillis();
        endTime = System.currentTimeMillis();
    }

    public void split() {
        split("");
    }

    public void split(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Split time for [" + tag + "]: " + (endTime - splitTime) + " ms");
        splitTime = endTime;
    }

    public void end() {
        end("");
    }
    public void end(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Final time for [" + tag + "]: " + (endTime - startTime) + " ms");
    }
}

使用示例:

public static Schedule getSchedule(Activity activity_context) {
        String scheduleJson = null;
        Schedule schedule = null;
/*->*/  Stopwatch stopwatch = new Stopwatch();

        InputStream scheduleJsonInputStream = activity_context.getResources().openRawResource(R.raw.skating_times);
/*->*/  stopwatch.split("open raw resource");

        scheduleJson = FileToString.convertStreamToString(scheduleJsonInputStream);
/*->*/  stopwatch.split("file to string");

        schedule = new Gson().fromJson(scheduleJson, Schedule.class);
/*->*/  stopwatch.split("parse Json");
/*->*/  stopwatch.end("Method getSchedule"); 
    return schedule;
}

控制台输出示例:

Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms
于 2015-01-27T18:44:53.853 回答
4

您可以使用 spring 核心项目中的秒表类:

代码:

StopWatch stopWatch = new StopWatch()
stopWatch.start();  //start stopwatch
// write your function or line of code.
stopWatch.stop();  //stop stopwatch
stopWatch.getTotalTimeMillis() ; ///get total time

秒表文档: 简单的秒表,允许对多个任务进行计时,显示每个命名任务的总运行时间和运行时间。隐藏 System.currentTimeMillis() 的使用,提高应用程序代码的可读性并降低计算错误的可能性。请注意,此对象并非设计为线程安全的,也不使用同步。此类通常用于在概念验证和开发过程中验证性能,而不是作为生产应用程序的一部分。

于 2018-03-08T08:18:54.867 回答
3

如果只是想知道时间,您可以尝试这种方式。

long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));    
于 2013-12-06T05:48:51.857 回答
3

在 Java 8 中引入了一个名为的新类Instant。根据文档:

Instant 表示时间线上一纳秒的开始。此类对于生成表示机器时间的时间戳很有用。瞬间的范围需要存储一个大于 long 的数字。为了实现这一点,该类存储了一个表示纪元秒的 long 和一个表示纳秒秒的 int,它们始终介于 0 和 999,999,999 之间。纪元秒是从标准 Java 纪元 1970-01-01T00:00:00Z 开始测量的,其中纪元之后的瞬间具有正值,而更早的瞬间具有负值。对于纪元秒和纳秒部分,较大的值在时间线上总是比较小的值晚。

这可以用作:

Instant start = Instant.now();
try {
    Thread.sleep(7000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

它打印PT7.001S

于 2015-06-22T09:02:49.340 回答
2

如果 java 有更好的功能支持,那就太好了,这样需要测量的动作可以被包装到一个块中:

measure {
   // your operation here
}

在java中,这可以通过匿名函数来完成,看起来太冗长了

public interface Timer {
    void wrap();
}


public class Logger {

    public static void logTime(Timer timer) {
        long start = System.currentTimeMillis();
        timer.wrap();
        System.out.println("" + (System.currentTimeMillis() - start) + "ms");
    }

    public static void main(String a[]) {
        Logger.logTime(new Timer() {
            public void wrap() {
                // Your method here
                timeConsumingOperation();
            }
        });

    }

    public static void timeConsumingOperation() {
        for (int i = 0; i<=10000; i++) {
           System.out.println("i=" +i);
        }
    }
}
于 2015-01-16T18:06:35.203 回答
2

您可以使用javaagent修改 java 类字节,动态添加监控代码。github 上有一些开源工具可以为您做到这一点。
如果你想自己做,只需实现javaagent,使用javassist修改你要监控的方法,以及方法返回之前的监控代码。它很干净,你可以监控你甚至没有源代码的系统.

于 2015-09-21T14:28:54.407 回答
2

这是漂亮的打印字符串准备好格式化的秒数,类似于谷歌搜索时间:

        long startTime = System.nanoTime();
        //  ... methodToTime();
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        long seconds = (duration / 1000) % 60;
        // formatedSeconds = (0.xy seconds)
        String formatedSeconds = String.format("(0.%d seconds)", seconds);
        System.out.println("formatedSeconds = "+ formatedSeconds);
        // i.e actual formatedSeconds = (0.52 seconds)
于 2016-12-15T09:25:22.020 回答
2

我实现了一个简单的计时器,我认为它非常有用:

public class Timer{
    private static long start_time;

    public static double tic(){
        return start_time = System.nanoTime();
    }

    public static double toc(){
        return (System.nanoTime()-start_time)/1000000000.0;
    }

}

这样你就可以为一个或多个动作计时:

Timer.tic();
// Code 1
System.out.println("Code 1 runtime: "+Timer.toc()+" seconds.");
// Code 2
System.out.println("(Code 1 + Code 2) runtime: "+Timer.toc()+"seconds");
Timer.tic();
// Code 3
System.out.println("Code 3 runtime: "+Timer.toc()+" seconds.");
于 2016-12-29T09:10:23.660 回答
1

System.nanoTime()是一个非常精确的系统实用程序,用于测量执行时间。但请注意,如果您在抢占式调度程序模式(默认)下运行,此实用程序实际上测量的是挂钟时间而不是 CPU 时间。因此,您可能会注意到每次运行的执行时间值不同,具体取决于系统负载。如果您寻找 CPU 时间,我认为以实时模式运行您的程序就可以了。你必须使用 RT linux。链接:使用 Linux 进行实时编程

于 2013-07-03T07:55:34.887 回答
1

在 java ee 中对我有用的策略是:

  1. @AroundInvoke;注释的方法创建一个类

    @Singleton
    public class TimedInterceptor implements Serializable {
    
        @AroundInvoke
        public Object logMethod(InvocationContext ic) throws Exception {
            Date start = new Date();
            Object result = ic.proceed();
            Date end = new Date();
            System.out.println("time: " + (end.getTime - start.getTime()));
            return result;
        }
    }
    
  2. 注释要监视的方法:

    @Interceptors(TimedInterceptor.class)
    public void onMessage(final Message message) { ... 
    

我希望这会有所帮助。

于 2017-07-06T12:47:55.437 回答
1

对于 java 8+,另一种可能的解决方案(更通用,func 样式且没有方面)可能是创建一些接受代码作为参数的实用程序方法

public static <T> T timed (String description, Consumer<String> out, Supplier<T> code) {
    final LocalDateTime start = LocalDateTime.now ();
    T res = code.get ();
    final long execTime = Duration.between (start, LocalDateTime.now ()).toMillis ();
    out.accept (String.format ("%s: %d ms", description, execTime));
    return res;
}

调用代码可能是这样的:

public static void main (String[] args) throws InterruptedException {
    timed ("Simple example", System.out::println, Timing::myCode);
}

public static Object myCode () {
    try {
        Thread.sleep (1500);
    } catch (InterruptedException e) {
        e.printStackTrace ();
    }
    return null;
}
于 2019-09-30T11:28:34.287 回答
0

也可以实现 Timer 接口并在您的类的任何方法上执行

import java.util.function.*;

public interface Timer {

    default void timeIt(Runnable r) {
        timeIt(() -> { r.run(); return 0;});
    }

    default <S,T> T timeIt(Function<S,T> fun, S arg) {
        long start = System.nanoTime();
        T result = fun.apply(arg);
        long stop = System.nanoTime();
        System.out.println("Time: " + (stop-start)/1000000.0 + " msec");
        return result;
    }

    default <T> T timeIt(Supplier<T> s) {
        return timeIt(obj -> s.get(), null);
    }
}

用法:

class MyClass implements Timer ..

timeIt(this::myFunction); 
于 2021-09-17T12:25:35.213 回答
0

这里有很多有效的答案,所有这些都是在方法中实现的。为了制作一个通用的计时方法,我通常有一个Timing由以下组成的类。

public record TimedResult<T>(T result, Duration duration) {}

public static Duration time(Runnable r) {
    var s = Instant.now();
    r.run();
    var dur = Duration.between(s, Instant.now());
    return dur;
}

public static <T> TimedResult<T> time(Callable<T> r) throws Exception {
    var s = Instant.now();
    T res = r.call();
    var dur = Duration.between(s, Instant.now());
    return new TimedResult<>(res, dur);
}

这足以传递RunnableCallable

Duration result = Timing.time(() -> {
    // do some work.
});

TimedResult<String> result = Timing.time(() -> {
    // do some work.
    return "answer";
});

Duration timeTaken = result.duration();
String answer = result.result();
于 2021-12-11T06:31:05.273 回答
-1

纯 Java SE 代码,无需添加依赖,使用TimeTracedExecuter

public static void main(String[] args) {

    Integer square = new TimeTracedExecutor<>(Main::calculateSquare)
                .executeWithInput("calculate square of num",5,logger);

}
public static int calculateSquare(int num){
    return num*num;
}

会产生这样的结果:

INFO: It took 3 milliseconds to calculate square of num

自定义可重用类:TimeTracedExecutor

import java.text.NumberFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.function.Function;
import java.util.logging.Logger;

public class TimeTracedExecutor<T,R> {
    Function<T,R> methodToExecute;

    public TimeTracedExecutor(Function<T, R> methodToExecute) {
        this.methodToExecute = methodToExecute;
    }

    public R executeWithInput(String taskDescription, T t, Logger logger){
        Instant start = Instant.now();
        R r= methodToExecute.apply(t);
        Instant finish = Instant.now();
        String format = "It took %s milliseconds to "+taskDescription;
        String elapsedTime = NumberFormat.getNumberInstance().format(Duration.between(start, finish).toMillis());
        logger.info(String.format(format, elapsedTime));
        return r;
    }
}
于 2020-04-28T08:22:58.000 回答