web-dev-qa-db-fra.com

Comment calculer le temps écoulé d'un événement en Java?

Quel est un moyen simple/facile d'accéder à l'horloge système à l'aide de Java, afin de pouvoir calculer le temps écoulé d'un événement?

52
kafuchau

J'éviterais d'utiliser System.currentTimeMillis() pour mesurer le temps écoulé. currentTimeMillis() renvoie l'heure de l'horloge murale, qui peut changer (par exemple: heure d'été, utilisateur administrateur changeant l'horloge) et fausser vos mesures d'intervalle.

System.nanoTime() , en revanche, renvoie le nombre de nanosecondes depuis "un certain point de référence" (par exemple, le démarrage de la JVM), et ne serait donc pas sensible aux changements d'horloge système.

81
Leigh

Ceci est un exemple de code.

long startTime = System.currentTimeMillis();
// Run some code;
long stopTime = System.currentTimeMillis();

System.out.println("Elapsed time was " + (stopTime - startTime) + " miliseconds.");
25
jjnguy

Apache Commons-Lang propose également la classe StopWatch adaptée à votre objectif. Il utilise System.currentTimeMillis (), vous aurez donc toujours des problèmes de résolution, mais vous pouvez faire une pause et faire des temps au tour et autres. Je l'utilise maintenant en standard pour les statistiques des événements.

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

9
Spencer Kormos

Le Réponse de Leigh est correct.

Java.time

Java 8 et versions ultérieures ont le framework Java.time intégré.

Un Instant est un moment sur la timeline en UTC avec une résolution en nanosecondes (jusqu'à 9 chiffres d'une fraction décimale de seconde). La méthode now saisit l'instant date-heure actuel.

Instant now = Instant.now();

2016-03-12T04: 29: 39.123Z

Vous pouvez calculer le temps écoulé entre une paire d'objets Instant sous la forme Duration . La durée utilise une résolution en nanosecondes avec une valeur maximale des secondes qui peut être maintenue dans une longue. Ceci est supérieur à l'âge estimé actuel de l'univers.

Duration duration = Duration.between( startInstant , stopInstant );

La sortie par défaut de Duration::toString est au format standard ISO 8601 . Vous pouvez également demander un nombre total de nanosecondes ( toNanos ) ou de millisecondes ( toMillis ), ainsi que d'autres montants.

Java 8

Dans Java 8, l'extraction du moment actuel ne se résout qu'à une résolution en millisecondes (jusqu'à 3 chiffres d'une fraction décimale de seconde). Ainsi, alors que les classes Java.time peuvent stocker nanosecondes, ils ne peuvent déterminer le moment actuel qu'en millisecondes. Cette limitation est due à un problème hérité (la valeur par défaut Clock utilise System.currentTimeMillis() ).

Java 9

Dans Java 9 et versions ultérieures, l'implémentation par défaut Clock peut déterminer le moment actuel avec une résolution pouvant atteindre la nanoseconde. En fait, cela dépend de la finesse du matériel d'horloge de votre ordinateur.

Voir cette page de problème OpenJDK pour plus d'informations: Augmentez la précision de l'implémentation de Java.time.Clock.systemUTC ()

Micro Benchmark

Si votre objectif est l'analyse comparative, assurez-vous de regarder d'autres questions telles que:

Des cadres sont disponibles pour faciliter l'analyse comparative de courte durée.

7
Basil Bourque

Java.lang.System.currentTimeMillis() ou Java.lang.System.nanoTime() devrait fonctionner pour mesurer le temps écoulé.

5
tvanfosson

Voici une petite classe StopWatch que j'ai écrite en utilisant System.nanoTime () comme suggéré dans la réponse de Leigh:

public class StopWatch {
    // Constructor
    public StopWatch() {
    }

    // Public API
    public void start() {
        if (!_isRunning) {
            _startTime = System.nanoTime();
            _isRunning = true;
        }
    }

    public void stop() {
        if (_isRunning) {
            _elapsedTime += System.nanoTime() - _startTime;
            _isRunning = false;
        }
    }

    public void reset() {
        _elapsedTime = 0;
        if (_isRunning) {
            _startTime = System.nanoTime();
        }
    }

    public boolean isRunning() {
        return _isRunning;
    }

    public long getElapsedTimeNanos() {
        if (_isRunning) {
            return System.nanoTime() - _startTime;
        }
        return _elapsedTime;
    }

    public long getElapsedTimeMillis() {
        return getElapsedTimeNanos() / 1000000L;
    }

    // Private Members
    private boolean _isRunning = false;
    private long _startTime = 0;
    private long _elapsedTime = 0;
}
3
Wilhem Meignan