Maison > Java > javaDidacticiel > le corps du texte

Comment le code source de Spring Boot implémente StopWatch pour compter élégamment la consommation de temps

王林
Libérer: 2023-05-11 14:13:13
avant
1105 Les gens l'ont consulté

Introduction

Hier, un golfeur m'a demandé si je pouvais lui expliquer ce que signifie l'annotation @SpringBootApplication et comment fonctionne Spring Boot, alors je l'y ai emmené après avoir regardé le code source de. cette annotation et la méthode run() de la classe SpringApplication, il l'a immédiatement compris.

Ne me dites pas, le processus de recherche du code source est vraiment intéressant Non, j'ai découvert un point intéressant.

public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	......
	stopWatch.stop();
}
Copier après la connexion

Spring Boot utilise StopWatch pour compter la consommation de temps, et généralement, nous utilisons System.currentTimeMillis() pour compter la consommation de temps, n'est-ce pas ? Programmation Meow ???? Il existe un tel morceau de code dans le projet open source, lorsqu'il s'agit des aspects de traitement unifié des journaux.

@Around("webLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    long startTime = System.currentTimeMillis();
    long endTime = System.currentTimeMillis();
    webLog.setSpendTime((int) (endTime - startTime));
}
Copier après la connexion

En comparaison, nous pouvons constater que System.currentTimeMillis() fourni par JDK n'est pas aussi concis et clair que StopWatch fourni par Spring.

Utilisation de StopWatch

Surtout dans le cas du multitâche, StopWatch est si simple à utiliser ????!

// 创建一个 StopWatch 实例
StopWatch sw = new StopWatch("沉默王二是傻 X");
// 开始计时
sw.start("任务1");
Thread.sleep(1000);
// 停止计时
sw.stop();
System.out.printf("任务1耗时:%d%s.\n", sw.getLastTaskTimeMillis(), "ms");
sw.start("任务2");
Thread.sleep(1100);
sw.stop();
System.out.printf("任务2耗时:%d%s.\n", sw.getLastTaskTimeMillis(), "ms");
System.out.printf("任务数量:%s,总耗时:%ss.\n", sw.getTaskCount(), sw.getTotalTimeSeconds());
Copier après la connexion

Tu vois, c'est très simple ?

  • Créez d'abord un nouvel objet StopWatch

  • puis commencez à chronométrer

    #🎜🎜 ## 🎜🎜#
  • Ensuite, arrêtez le chronomètre
  • Enfin obtenez le décalage horaire via sw.getLastTaskTimeMillis()
  • #🎜 🎜## 🎜🎜#Si vous passez à System.currentTimeMillis(), vous mourrez. Vous devez d'abord déclarer plusieurs variables locales de type long, puis soustraire la première de la seconde, et soustraire la seconde de la troisième. un. Soyez un peu négligent (surtout lorsque vous utilisez la méthode CV, il est facile de faire des erreurs.

  • En plus de l'heure locale, vous pouvez également obtenir la durée totale via sw.getTotalTimeSeconds().

La tâche 1 a pris 1002 ms

De plus, StopWatch fournit également une méthode sw.prettyPrint() pour imprimer des résultats magnifiquement formatés :
# 🎜🎜#

StopWatch 'Le Roi Silencieux est stupide' : durée d'exécution = 2108529351 ns
------------------------- -------------------- ------
ns       %   Nom de la tâche

------------ -------------------- -------------
1004338467 048% Tâche 1

1104190884 052% Tâche 2

Il y a une consommation de temps et un pourcentage d'occupation, et le nom de la tâche est très clair.

En plus de Spring, la bibliothèque d'outils hutool et le package d'outils communs Apache fournissent leur propre StopWatch.


En regardant le code source de StopWatch dans la bibliothèque d'outils hutool, nous pouvons voir que cette classe provient en fait de StopWatch.java de Spring, et son utilisation est exactement pareil.

Cela montre que l'auteur de hutool pense aussi que Spring's StopWatch est bien écrit, hahaha ????. Comment le code source de Spring Boot implémente StopWatch pour compter élégamment la consommation de temps

Utilisez Beyond compare pour comparer

Après avoir comparé avec Beyond compare, nous pouvons également constater qu'à l'exception d'un commentaire chinois et d'un commentaire anglais, les codes sont presque les mêmes. La méthode setKeepTaskList est assez différente.

Comment le code source de Spring Boot implémente StopWatch pour compter élégamment la consommation de temps

C'est-à-dire que si vous n'utilisez pas Spring Family Bucket dans votre projet et utilisez uniquement la boîte à outils hutool, vous pouvez utiliser le StopWatch de hutool pour remplacer System .currentTimeMillis().

En analysant le code source de la méthode stop de StopWatch :

public void stop() throws IllegalStateException {
	if (null == this.currentTaskName) {
		throw new IllegalStateException("Can't stop StopWatch: it's not running");
	}
	final long lastTime = System.nanoTime() - this.startTimeNanos;
	this.totalTimeNanos += lastTime;
	this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
	if (null != this.taskList) {
		this.taskList.add(this.lastTaskInfo);
	}
	++this.taskCount;
	this.currentTaskName = null;
}
Copier après la connexion

En fait, on peut constater que StopWatch est chronométré en interne via System.nanoTime(), qui est essentiellement le identique à System.currentTimeMillis( ) La différence n'est pas énorme.

Comment le code source de Spring Boot implémente StopWatch pour compter élégamment la consommation de tempsnanoTime est plus granulaire que currentTimeMillis. Le premier est en nanosecondes et le second en millisecondes.

Notez que les deux sont des méthodes natives, c'est-à-dire que la granularité de la valeur dépend en réalité du système d'exploitation sous-jacent.

Après avoir vu cela, vous réaliserez peut-être soudainement que StopWatch n'est que System.currentTimeMillis() dans un manteau ?

Mais ce qui est merveilleux c'est que ce manteau est assez beau et assez élégant. StopWatch peut enregistrer le nom de chaque sous-tâche et imprimer les résultats dans un format plus convivial, en particulier pour les statistiques multitâches.

Comment le code source de Spring Boot implémente StopWatch pour compter élégamment la consommation de tempsBien sûr, en plus de choisir StopWatch de Spring et hutool, StopWatch d'Apache commons-lang3 est également une bonne option, qui est plus flexible et modifiable.

StopWatch sw = StopWatch.createStarted();
Thread.sleep(1000);
System.out.printf("耗时:%dms.\n", sw.getTime());
Copier après la connexion

Les deux autres objets StopWatch créés via new, commons-lang3 peuvent également être complétés via createStarted (créer et démarrer immédiatement), create (créer).

Vous pouvez également appeler la méthode suspend pour suspendre le chronométrage, la méthode de reprise pour reprendre le chronométrage et la méthode de réinitialisation pour redémarrer le chronométrage.

// 暂停计时
sw.suspend();
System.out.printf("暂停耗时:%dms.\n", sw.getTime());
// 恢复计时
sw.resume();
System.out.printf("恢复耗时:%dms.\n", sw.getTime());
// 停止计时
sw.stop();
System.out.printf("总耗时:%dms.\n", sw.getTime());
// 重置计时
sw.reset();
// 开始计时
sw.start();
System.out.printf("重置耗时:%dms.\n", sw.getTime());
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal