web-dev-qa-db-fra.com

Classe chronomètre pour Java

Quelle classe Java devez-vous utiliser pour mesurer les performances temporelles?

(On peut utiliser n'importe quelle classe de date/heure, mais la raison pour laquelle je pose la question est en .Net, il y a une classe Stopwatch class à cet effet)

49
ripper234

Le cadre Spring a une excellente classe 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());

Cela produit:

 Chronomètre 'Mon chronomètre': durée (millis) = 10000 
 -----------------------------------------
 ms% Nom de la tâche 
 -----------------------------------------
 02000 020% initialisation 
 05000 050% de traitement 
 03000 030% finalisant 
93
Adam Paynter

Java.lang.System.nanoTime ()

Ou vous pouvez utiliser le chronomètre fourni dans Apache commons. Cette classe utilise Java.lang.System.currentTimeMillis ()

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

5
Kevin Crowell

Voici un exemple d'utilisation de Chronomètre pour définir plusieurs mesures en annotant des méthodes dédiées. Très utile et très simple à utiliser pour mesurer, par exemple Appel de service sur plusieurs appels/opérations intégrés, etc.

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

Conseiller

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 Annotation

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 {

}

Annote ton code

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

Sortie

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
2
e double you

Découvrez perf4j. Le chronomètre du printemps est principalement destiné au développement local. Perf4j peut prendre en charge votre synchronisation de type POC ainsi que sur un environnement de production. 

1
user2262148

Si vous souhaitez simplement le mesurer, utilisez une classe de chronomètre, ou peut-être simplement un chronomètre.

Si vous voulez faire plus vite, considérez ceci .

0
Mike Dunlavey

Si vous utilisez JDK 9+, vous pouvez utiliser l'enregistreur de vol. Il a une surcharge extrêmement faible et utilise un TSC invariant pour la synchronisation, ce qui est moins intrusif que 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");
    }
}

Vous pouvez également démarrer un enregistrement depuis la ligne de commande (-XX: StartFlightRecording), puis activer l'événement dans un fichier de configuration (.jfc) (si vous le désactivez par défaut, @Enable (false)).

Ainsi, le JIT optimisera généralement les appels StopWatch (analyse d'échappement, alignement, élimination de code mort, etc.), de sorte que vous ne payez la pénalité que lorsque vous souhaitez mesurer quelque chose. 

0
Kire Haglin

Vous pouvez essayer System.currentTimeMillis (), mais il existe également de bonnes options profiling sous certains IDE connus, tels que Eclipse et netbeans. De plus, en dehors de l'EDI, vous pouvez essayer profileurs autonomes dans vos tâches de mesure des performances. Je pense qu'en utilisant les profileurs, vous obtiendrez de meilleurs résultats qu'en utilisant System.currentTimeMillis ().

0
daniel

Le mieux est d’utiliser System.nanoTime (), cependant, si vous souhaitez obtenir des ticks (ticks écoulés) comme System.Diagnostics.Stopwatch, vous devez ensuite convertir les nanosecondes en ticks (1 tick = 100 nanosecondes), puis commencer à effectuer la conversion entre elles. nanos et millis, secs, minutes, hours, puis formatez finalement la sortie en une représentation Time telle que celle de la méthode Elapsed () (hh: mm: ss.sssssss). Cependant, il semblerait que Dates en Java utilise seulement 3 millisecondes. (hh: mm: ss.sss), vous devez donc également vous entraîner au format.

J'ai fait une classe Chronomètre pour Java Vous pouvez l'obtenir auprès de: http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-Java.html

Exemple:

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

Le résultat:

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

J'espère que cela t'aides.

0