Java的秒表类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1238678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:15:05  来源:igfitidea点击:

Stopwatch class for Java

javaperformancemeasurement

提问by ripper234

Which Java class should you use for time performance measurements?

您应该使用哪个 Java 类来测量时间性能?

(One could use any date/time class, but the reason I'm asking is in .Net there's a designated Stopwatchclass for this purpose)

(可以使用任何日期/时间类,但我问的原因是在 .Net 中有一个用于此目的的指定秒表类)

采纳答案by Adam Paynter

The Spring Framework has an excellent StopWatchclass:

Spring 框架有一个很好的StopWatch

StopWatch stopWatch = new StopWatch("My Stop Watch");

stopWatch.start("initializing");
Thread.sleep(2000); // simulated work
stopWatch.stop();

stopWatch.start("processing");
Thread.sleep(5000); // simulated work
stopWatch.stop();

stopWatch.start("finalizing");
Thread.sleep(3000); // simulated work
stopWatch.stop();

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

This produces:

这产生:

    StopWatch 'My Stop Watch': running time (millis) = 10000
    -----------------------------------------
    ms     %     Task name
    -----------------------------------------
    02000  020%  initializing
    05000  050%  processing
    03000  030%  finalizing

回答by Kevin Crowell

java.lang.System.nanoTime()

java.lang.System.nanoTime()

Or you can use the StopWatch that is supplied in apache commons. This class uses java.lang.System.currentTimeMillis()

或者您可以使用 apache commons 中提供的 StopWatch。这个类使用 java.lang.System.currentTimeMillis()

http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/StopWatch.html

http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/StopWatch.html

回答by daniel

You can try System.currentTimeMillis(), but also there a good profilingoptions under some well known IDEs, such as eclipse and netbeans. Also, away from the IDE, you can try standalone profilersin your performance measurements tasks. I think that by using profilers you will get better results than using System.currentTimeMillis().

您可以尝试System.currentTimeMillis(),但在一些众所周知的 IDE(例如 eclipse 和 netbeans)下也有很好的分析选项。此外,远离 IDE,您可以在性能测量任务中尝试使用独立的分析器。我认为通过使用分析器,您将获得比使用System.currentTimeMillis()更好的结果。

回答by Mike Dunlavey

If you just want to measure it, use a stopwatch class, or maybe just a stopwatch.

如果您只想测量它,请使用秒表课程,或者只是秒表。

If you want to make it faster, consider this.

如果你想让它更快,请考虑这个

回答by Carlos Quintanilla

The best is to use System.nanoTime(), however, if you want to get Ticks (elapsed Ticks) like System.Diagnostics.Stopwatch does you then need to convert nanoseconds to Ticks (1 Tick = 100 Nanoseconds) and then start converting between nanos and millis, secs, mins, hours, then finally format the output into a Time representation such as the one of the Elapsed() method (hh:mm:ss.sssssss), however, looks like Dates in Java use only 3 milliseconds (hh:mm:ss.sss), so you also need to workout the format as well.

最好是使用 System.nanoTime(),但是,如果您想获得像 System.Diagnostics.Stopwatch 这样的 Ticks(经过的 Ticks),那么您是否需要将纳秒转换为 Ticks(1 Tick = 100 纳秒),然后开始在它们之间进行转换nanos 和毫秒、秒、分钟、小时,然后最终将输出格式化为时间表示形式,例如 Elapsed() 方法之一(hh:mm:ss.sssssss),但是,Java 中的日期看起来仅使用 3 毫秒(hh:mm:ss.sss),所以你也需要锻炼格式。

I did one Stopwatch class for Java you can get it from: http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html

我为 Java 做了一个秒表类,你可以从:http: //carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html

Example:

例子:

package stopwatchapp;
import java.math.BigInteger;
public class StopwatchApp {
    public static void main(String[] args) {

        Stopwatch timer = new Stopwatch();
        timer.start();
        Fibonacci(40);
        timer.stop();

        System.out.println("Elapsed time in ticks: " 
            + timer.getElapsedTicks());
        System.out.println("Elapsed time in milliseconds: " 
            + timer.getElapsedMilliseconds());
        System.out.println("Elapsed time in seconds: " 
            + timer.getElapsedSeconds());
        System.out.println("Elapsed time in minutes: " 
            + timer.getElapsedMinutes());
        System.out.println("Elapsed time in hours: " 
            + timer.getElapsedHours());
        System.out.println("Elapsed time with format: " 
            + timer.getElapsed());
    }

    private static BigInteger Fibonacci(int n)
    {
        if (n < 2)
            return BigInteger.ONE;
        else
            return Fibonacci(n - 1).add(Fibonacci(n - 2));
    }
}

The output:

输出:

// Elapsed time in ticks: 33432284
// Elapsed time in milliseconds: 3343
// Elapsed time in seconds: 3
// Elapsed time in minutes: 0
// Elapsed time in hours: 0
// Elapsed time with format: 00:00:03.3432284

Hope this helps.

希望这可以帮助。

回答by user1988071

private void WaitTimer(long ms)
{
    long t = 0;
    long x = System.currentTimeMillis();

    while(t < ms)
    {
       t = System.currentTimeMillis() - x;
    }
}

回答by user2262148

Check out perf4j. Spring's stop watch is mainly for local development. Perf4j can support both your POC type timing as well as on a production environment.

查看 perf4j。Spring的秒表主要是针对本地开发的。Perf4j 可以支持您的 POC 类型计时以及生产环境。

回答by e double you

This is an example how to use StopWatch to set multiple measurements by annotating dedicated methods. Very useful and very simple to use to measure e.g. Service call over multiple embedded call / operation and so on.

这是一个如何使用 StopWatch 通过注释专用方法来设置多个测量值的示例。非常有用且非常易于用于测量例如多个嵌入式调用/操作上的服务调用等。

StopWatchHierarchy

秒表层级

package ch.vii.spring.aop;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
public class ProfilingMethodInterceptor implements MethodInterceptor {

    private static final Logger log = LoggerFactory.getLogger(ProfilingMethodInterceptor.class);

    public Object invoke(MethodInvocation invocation) throws Throwable {

        if (log.isInfoEnabled()) {
            String stopWatchName = invocation.getMethod().toGenericString();
            StopWatchHierarchy stopWatch = StopWatchHierarchy.getStopWatchHierarchy(stopWatchName);

            String taskName = invocation.getMethod().getName();
            stopWatch.start(taskName);

            try {
                return invocation.proceed();
            } finally {
                stopWatch.stop();
            }
        } else {
            return invocation.proceed();
        }
    }

    static class StopWatchHierarchy {
        private static final ThreadLocal<StopWatchHierarchy> stopwatchLocal = new ThreadLocal<StopWatchHierarchy>();
        private static final IndentStack indentStack = new IndentStack();

        static StopWatchHierarchy getStopWatchHierarchy(String id) {

            StopWatchHierarchy stopWatch = stopwatchLocal.get();
            if (stopWatch == null) {
                stopWatch = new StopWatchHierarchy(id);
                stopwatchLocal.set(stopWatch);
            }
            return stopWatch;
        }

        static void reset() {
            stopwatchLocal.set(null);
        }

        final StopWatch stopWatch;
        final Stack stack;

        StopWatchHierarchy(String id) {
            stopWatch = new StopWatch(id);
            stack = new Stack();
        }

        void start(String taskName) {
            if (stopWatch.isRunning()) {
                stopWatch.stop();
            }
            taskName = indentStack.get(stack.size) + taskName;
            stack.push(taskName);
            stopWatch.start(taskName);
        }

        void stop() {
            stopWatch.stop();
            stack.pop();
            if (stack.isEmpty()) {
                log.info(stopWatch.prettyPrint());
                StopWatchHierarchy.reset();
            } else {
                stopWatch.start(stack.get());
            }
        }

    }

    static class Stack {
        private int size = 0;
        String elements[];

        public Stack() {
            elements = new String[10];
        }

        public void push(String e) {
            if (size == elements.length) {
                ensureCapa();
            }
            elements[size++] = e;
        }

        public String pop() {
            String e = elements[--size];
            elements[size] = null;
            return e;
        }

        public String get() {
            return elements[size - 1];
        }

        public boolean isEmpty() {
            return size == 0;
        }

        private void ensureCapa() {
            int newSize = elements.length * 2;
            elements = Arrays.copyOf(elements, newSize);
        }
    }

    static class IndentStack {
        String elements[] = new String[0];

        public String get(int index) {
            if (index >= elements.length) {
                ensureCapa(index + 10);
            }
            return elements[index];
        }

        private void ensureCapa(int newSize) {
            int oldSize = elements.length;
            elements = Arrays.copyOf(elements, newSize);
            for (int i = oldSize; i < elements.length; i++) {
                elements[i] = new String(new char[i]).replace("
package ch.vii.spring.aop;

import java.lang.reflect.Method;

import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ProfilingAdvisor extends AbstractPointcutAdvisor {

    private static final long serialVersionUID = 1L;

    private final StaticMethodMatcherPointcut pointcut = new StaticMethodMatcherPointcut() {
        public boolean matches(Method method, Class<?> targetClass) {
            return method.isAnnotationPresent(ProfileExecution.class);
        }
    };

    @Autowired
    private ProfilingMethodInterceptor interceptor;

    public Pointcut getPointcut() {
        return this.pointcut;
    }

    public Advice getAdvice() {
        return this.interceptor;
    }
}
", "| "); } } } }

Advisor

顾问

package ch.vii.spring.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface ProfileExecution {

}

ProfileExecution Annotation

ProfileExecution注解

package ch.vii.spring;                                                                                                                                                                 
import org.springframework.beans.factory.annotation.Autowired;                                      
import org.springframework.stereotype.Component;                                                    

import ch.vii.spring.aop.ProfileExecution;                                                          

@Component                                                                                          
public class Bean {                                                                                 
    @Autowired                                                                                      
    InnerBean innerBean;  

    @ProfileExecution                                                                               
    public void foo() {                                                                             
        innerBean.innerFoo();                                                                      
        innerBean.innerFoo2();                                                                      
        innerBean.innerFoo();                                                                       
    }                                                                                                                                                                                         
}  

public class InnerBean {
    @Autowired
    InnerInnerBean innerInnerBean;

    @ProfileExecution
    public void innerFoo() {
    }

    @ProfileExecution
    public void innerFoo2() {
        innerInnerBean.innerInnerFoo();
        innerInnerBean.innerInnerFoo();
        innerInnerBean.innerInnerFoo();
    }
}                                                                                                    

Annotate your code

注释您的代码

09:58:39.627 [main] INFO  c.v.s.aop.ProfilingMethodInterceptor - StopWatch 'public void ch.vii.spring.Bean.foo()': running time (millis) = 215
-----------------------------------------
ms     %     Task name
-----------------------------------------
00018  008 %  foo
00026  012 %  |   innerFoo
00001  000 %  foo
00016  007 %  |   innerFoo2
00038  018 %  |   |   innerInnerFoo
00000  000 %  |   innerFoo2
00024  011 %  |   |   innerInnerFoo
00028  013 %  |   innerFoo2
00024  011 %  |   |   innerInnerFoo
00029  013 %  |   innerFoo2
00000  000 %  foo
00011  005 %  |   innerFoo
00000  000 %  foo

Output

输出

@StackTrace(false)
static class StopWatch extends Event {
  int fib;
}

public static void main(String... args) throws IOException {
    Recording r = new Recording();
    r.start();
    for (int i = 0; i < 500000; i++) {
        StopWatch s = new StopWatch();
        s.begin();
        s.fib = fib(i%100);
        s.commit();
    }
    r.stop();
    Path p = Paths.get("recording.jfr");
    r.dump(p);
    for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
        System.out.println(e.getValue("fib") + " " + e.getDuration().toNanos() + " ns");
    }
}

回答by Kire Haglin

If you are using JDK 9+, you could use Flight Recorder. It has extremely low overhead and uses invariant TSC for timing, which is less intrusive than System.nanoTime()

如果您使用的是 JDK 9+,则可以使用 Flight Recorder。它具有极低的开销并使用不变的 TSC 进行计时,这比 System.nanoTime() 的侵入性小

Stopwatch sw = new Stopwatch();
sw.start();

// Your code here

sw.stop();
sw.printStatistics(System.out);

You can also start a recording from command line (-XX:StartFlightRecording) and then enable the event in a configuration file (.jfc) (if you disable it by default, @Enable(false))

您还可以从命令行 (-XX:StartFlightRecording) 开始录制,然后在配置文件 (.jfc) 中启用该事件(如果默认禁用它,@Enable(false))

That way the JIT will typically optimize away the StopWatch calls (escape analysis, inlining, deadcode elimination etc), so you only pay the penalty when you want to measure something.

这样,JIT 通常会优化掉 StopWatch 调用(转义分析、内联、死代码消除等),因此您只需在想要测量某些东西时付出代价。

回答by Oswaldo Junior

Performetricsprovides a convenient Stopwatch class. It can measure wall-clock time and more: it also measures CPU time, user time and system time, if you need more accuracy. It's small, free and you can download from Maven Central. More information and examples can be found here: https://obvj.net/performetrics

Performmetrics提供了一个方便的 Stopwatch 类。它可以测量挂钟时间等等:如果您需要更高的准确性,它还可以测量 CPU 时间、用户时间和系统时间。它小巧且免费,您可以从 Maven Central 下载。可以在此处找到更多信息和示例:https: //obvj.net/performetrics

+-----------------+----------------------+--------------+
| Counter         |         Elapsed time | Time unit    |
+-----------------+----------------------+--------------+
| Wall clock time |             85605718 | nanoseconds  |
| CPU time        |             78000500 | nanoseconds  |
| User time       |             62400400 | nanoseconds  |
| System time     |             15600100 | nanoseconds  |
+-----------------+----------------------+--------------+

This produces an output similar to the following:

这会产生类似于以下内容的输出:

##代码##

You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...) just by passing a custom parameter.

只需传递自定义参数,您就可以将指标转换为任何时间单位(纳秒、毫秒、秒等)。

PS: I am the author of the tool.

PS:我是该工具的作者。