Класс секундомера для Java - PullRequest
50 голосов
/ 06 августа 2009

Какой класс Java вы должны использовать для измерения производительности времени?

(Можно использовать любой класс даты / времени, но я спрашиваю об этом в .Net для этой цели есть специальный класс Секундомер )

Ответы [ 9 ]

96 голосов
/ 06 августа 2009

Spring Framework имеет отличный 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());

Это производит:

    StopWatch 'My Stop Watch': running time (millis) = 10000
    -----------------------------------------
    ms     %     Task name
    -----------------------------------------
    02000  020%  initializing
    05000  050%  processing
    03000  030%  finalizing
5 голосов
/ 06 августа 2009

java.lang.System.nanoTime ()

Или вы можете использовать секундомер, который поставляется в Apache Commons. Этот класс использует java.lang.System.currentTimeMillis ()

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

2 голосов
/ 20 февраля 2016

Это пример того, как использовать 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("\0", "|   ");
            }
        }
    }
}

Советник

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;
    }
}

ProfileExecution Аннотация

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 {

}

Аннотируйте свой код

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();
    }
}                                                                                                    

выход

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
1 голос
/ 09 апреля 2013

Проверьте perf4j. Весенний секундомер в основном для местного развития. Perf4j может поддерживать как синхронизацию вашего типа POC, так и в производственной среде.

0 голосов
/ 14 ноября 2018

Если вы используете JDK 9+, вы можете использовать Flight Recorder. Он имеет чрезвычайно низкие накладные расходы и использует для синхронизации инвариантный TSC, который менее навязчив, чем System.nanoTime ()

@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");
    }
}

Вы также можете начать запись из командной строки (-XX: StartFlightRecording), а затем включить событие в файле конфигурации (.jfc) (если вы отключите его по умолчанию, @Enable (false))

Таким образом, JIT, как правило, оптимизирует удаление вызовов StopWatch (анализ экранирования, встраивание, устранение мертвых кодов и т. Д.), Поэтому вы платите штраф только тогда, когда хотите что-то измерить.

0 голосов
/ 17 января 2013
private void WaitTimer(long ms)
{
    long t = 0;
    long x = System.currentTimeMillis();

    while(t < ms)
    {
       t = System.currentTimeMillis() - x;
    }
}
0 голосов
/ 12 мая 2011

Лучше всего использовать System.nanoTime (), однако, если вы хотите получить тики (прошедшие тики), такие как System.Diagnostics.Stopwatch, нужно ли вам затем преобразовывать наносекунды в тики (1 тик = 100 наносекунд) и начните преобразование между nanos и millis, secs, mins, hours, затем, наконец, отформатируйте вывод в представление Time, такое как метод Elapsed () (hh: mm: ss.sssssss), однако, похоже, что Dates в Java используются всего 3 миллисекунды (чч: мм: сс.ссс), так что вам также нужно потренироваться в формате.

Я сделал один класс Секундомер для Java Вы можете получить его от: http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html

Пример:

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));
    }
}

Выход:

// 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

Надеюсь, это поможет.

0 голосов
/ 18 ноября 2009

Если вы просто хотите измерить его, используйте класс секундомера или, может быть, просто секундомер.

Если вы хотите сделать это быстрее, учтите это .

0 голосов
/ 06 августа 2009

Вы можете попробовать System.currentTimeMillis () , но также есть хорошие профилирование опций в некоторых известных IDE, таких как eclipse и netbeans. Кроме того, вне среды IDE вы можете попробовать автономные профилировщики в своих задачах измерения производительности. Я думаю, что с помощью профилировщиков вы получите лучшие результаты, чем при использовании System.currentTimeMillis () .

...