227 votes

Dans log4j, vérification isDebugEnabled avant d’ouvrir améliore-t-il la performance ?

Je suis à l'aide de Log4J dans mon application pour l'enregistrement. Auparavant, j'étais l'utilisation de débogage appel comme:

Option 1:

logger.debug("some debug text");

mais certains liens suggèrent qu'il est préférable de vérifier isDebugEnabled() tout d'abord, comme:

Option 2:

boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
    logger.debug("some debug text");
}

Donc ma question est "Ne l'option 2 améliorer les performances de toute façon?".

Parce que dans tous les cas, Log4J cadre ont même vérifier debugEnabled. Pour l'option 2, il peut être bénéfique si nous sommes à l'aide de plusieurs debug déclaration de méthode ou une classe, où le cadre n'a pas besoin d'appeler l' isDebugEnabled() méthode plusieurs fois (à chaque appel); dans ce cas, il appelle isDebugEnabled() méthode qu'une seule fois, et si Log4J est configuré au niveau de débogage alors effectivement il appelle isDebugEnabled() méthode deux fois:

  1. Dans le cas de l'attribution de la valeur à debugEnabled variable, et
  2. En fait appelé par l'enregistreur.méthode debug ().

Je ne pense pas que si nous écrire plusieurs logger.debug() déclaration de la méthode ou de la classe et en appelant debug() méthode selon l'option 1, puis c'est au-dessus de Log4J cadre en comparaison avec l'option 2. Depuis isDebugEnabled() est une très petite méthode (en termes de code), il pourrait être un bon candidat pour inline.

262voto

erickson Points 127945

Dans ce cas particulier, l'Option 1 est mieux.

La garde déclaration en cochant ( isDebugEnabled()) est là pour éviter potentiellement coûteux calcul du message de log quand il s'agit de l'invocation de l' toString() méthodes d'objets divers et de la concaténation des résultats.

Dans l'exemple donné, le message de log est une constante chaîne, afin de laisser l'enregistreur de jeter, il est tout aussi efficace que le contrôle de l'enregistreur de données est activé, et il réduit la complexité du code, car il y a moins de branches.

Encore mieux est d'utiliser un plus up-to-date de journalisation où le journal des déclarations de prendre une spécification de format et une liste d'arguments pour être remplacé par l'enregistreur de données—mais "paresseusement," si et seulement si l'enregistreur est activé. C'est l'approche adoptée par slf4j.

Voir ma réponse à une question connexe pour plus d'informations et un exemple de faire quelque chose comme cela avec log4j.

32voto

Ceki Points 8781

Depuis que dans l'option 1 de la chaîne de message est une constante, il n'y a absolument aucun gain dans l'emballage de la déclaration logging avec une condition, au contraire, si l'instruction de journal de débogage est activé, vous serez en évaluer deux fois, une fois dans l' isDebugEnabled() méthode et une fois dans debug() méthode. Le coût de l'invocation d' isDebugEnabled() est de l'ordre de 5 à 30 nanosecondes, ce qui devrait être négligeable pour la plupart des fins pratiques. Ainsi, l'option 2 n'est pas souhaitable, car elle pollue votre code et fournit aucune autre gain.

23voto

atc Points 1553

À l'aide de l' isDebugEnabled() est réservé pour quand vous êtes en train de construire des journaux de messages par concaténation de Chaînes de caractères:

Var myVar = new MyVar();
log.debug("My var is " + myVar + ", value:" + myVar.someCall());

Cependant, dans votre exemple, il n'y a pas de gain de vitesse que vous êtes juste de l'enregistrement d'une Chaîne et de ne pas effectuer des opérations, telles que la concaténation. Par conséquent, vous êtes juste en ajoutant le ballonnement de votre code et de le rendre plus difficile à lire.

Personnellement, j'utilise le Java 1.5 format des appels dans la Chaîne de classe comme ceci:

Var myVar = new MyVar();
log.debug(String.format("My var is '%s', value: '%s'", myVar, myVar.someCall()));

Je doute qu'il ya beaucoup de l'optimisation, mais c'est plus facile à lire.

8voto

Andrew Carr Points 461

Version courte: Vous pourriez aussi bien faire le booléen isDebugEnabled() vérifier.

Raisons:
1 - Si compliqué logique / string concat. est ajouté à votre instruction de débogage, vous aurez déjà le vérifier en place.
2 - Vous n'avez pas à inclure la déclaration sur le "complexe" des instructions de débogage. Toutes les instructions sont incluses.
3 - l'Appel du journal.debug exécute les opérations suivantes avant d'enregistrement:

if(repository.isDisabled(Level.DEBUG_INT))

C'est fondamentalement la même que l'appel à la journal de. ou un chat. isDebugEnabled().

TOUTEFOIS! C'est ce que le log4j dans l'esprit des développeurs (car il est dans leur javadoc et vous devriez probablement passer par lui).

C'est la méthode


C'est la javadoc pour elle


          return;

6voto

Sathya Points 797

L'Option 2 est mieux.

En soi, il n'améliore pas les performances. Mais il garantit les performances ne se dégradent pas. Voici comment.

Normalement, nous nous attendons à ce enregistreur.debug(someString);

Mais généralement, que la demande se développe, change beaucoup de mains, esp développeurs novices, vous avez pu voir

enregistreur.debug(ch1 + ch2 + str3 + str4);

et la comme.

Même si le niveau de journalisation est défini à l'ERREUR ou FATALE, la concaténation de chaînes de caractères ne se produisent ! Si l'application contient beaucoup de niveau de DEBUG messages avec des concaténations de chaîne, alors il faut certainement un gain de performance surtout avec le jdk 1.4 ou ci-dessous. (Iam ne sais pas si plus tard les versions de jdk internall faire tout stringbuffer.append()).

C'est pourquoi l'Option 2 est à l'abri. Même la chaîne de concaténations de ne pas se produire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X