tutorial practices best java performance logging coding-style

java - practices - Encerrar llamadas a debug() en si isDebugEnabled(): ¿una buena política?



log4j tutorial (6)

Nuestro equipo tiene la política de hacer logging como

if (LOGGER.isDebugEnabled()) { LOGGER.debug("model[" + model + "]"); }

En lugar de simplemente llamar al método de registro de esta manera:

LOGGER.debug("model[" + model + "]");

Esta práctica es capaz de llevar a algunas mejoras de rendimiento , pero por otro lado hace que el código base sea más complejo. Nuestra aplicación no tiene problemas de rendimiento, probablemente nunca lo hará, el argumento para la introducción de la política fue simplemente que es una buena práctica, por lo que se utilizará cada vez que realicemos el registro.

¿Crees que es una buena política?


Creo que tiene sentido poner la llamada isDebugEnabled () antes de escribir el mensaje de registro. Que fácilmente puede actualizar su mensaje de registro más tarde. Usamos el siguiente código para hacer que los mensajes de registro sean más flexibles.

if (LOGGER.isDebugEnabled()) { String msg = "A Message {0} you can put {1} differet Objects in {2}"; //$NON-NLS-1$ Object[] args = new Object[] {file1.toString(),new Integer(23),anObject}; LOGGER.debug(MessageFormat.format(msg,args)); }

Cuando no tuvieras la sentencia if, perderías tiempo. Recuerda ... tu proyecto se hace más grande y tus mensajes de registro también.

Los mensajes de registro no deben ralentizar su código!


Debe usar SLF4J y hacer de log4j su implementación. Con SLF4J , puede eliminar isDebugEnabled() usando mensajes parametrizados.

Consulte la sección sobre el rendimiento de registro en las preguntas frecuentes de slf4j

Las siguientes dos líneas producirán exactamente el mismo resultado. Sin embargo, el segundo formulario superará al primer formulario en un factor de al menos 30, en caso de una declaración de registro deshabilitada.

logger.debug("The new entry is " + entry + ".");

logger.debug("The new entry is {}.", entry);


Es una buena política para aquellas ocasiones en que la cadena de registro que está creando realmente afectará significativamente el rendimiento. Esto podría ser por dos razones:

  • Se necesita mucho trabajo para construir la cadena (por ejemplo, tiene que hacer búsquedas o construir una cadena muy grande a partir de un montón de piezas muy pequeñas)
  • Está en un bucle que no está haciendo mucho otro trabajo (pero se llama muy a menudo), por lo que la proporción del tiempo dedicado a la creación de una cadena de registro simple es mayor

No debería ser una regla general, y espero que ambas situaciones sean relativamente raras.

Por supuesto, lo que realmente queremos es poder decir "Llamar al método de depuración, pasando un argumento que no es la propia cadena de depuración, pero es algo que sabe cómo construir la cadena de depuración, si y solo si es necesario." Esto sería feo en Java sin cierres concisos. (Incluso en un lenguaje con cierres en forma de expresiones lambda, la captura de las variables relevantes podría ser importante en algunas situaciones, dependiendo de cómo el lenguaje maneja la captura).


Estoy de acuerdo con la famosa cita de Michael A. Jackson :

La primera regla de la optimización del programa: no lo hagas.

La segunda regla de la optimización del programa: solo para expertos: no lo haga todavía.

Creo que en la mayoría de los casos no vale la pena hacer que el código base sea más complejo sin estar seguro de que la ganancia de rendimiento será notable / significativa.

Soy consciente de la mejora del rendimiento, pero creo que será responsabilidad del programador individual decidir si vale la pena agregar esas líneas de código adicionales en un caso particular. En la mayoría de los casos, las líneas adicionales solo están agregando complejidad sin ninguna ganancia notable en el lado del rendimiento.


No puedo encontrar la referencia en línea (quizás la leí en un libro) pero hubo un ejemplo de una llamada de BIOS que escribió una cadena en la pantalla.

El código escribió la cadena en la pantalla verificada para asegurarse de que la cadena no iba a salir de la pantalla y luego llamó a una función para escribir un carácter en la pantalla.

La función que escribió el carácter en la pantalla se comprobó para asegurarse de que el carácter no se escribiría fuera de la pantalla.

Al eliminar el código de verificación de la función que escribió el carácter en la pantalla se produjo un aumento masivo de la velocidad. El fue porque la impresión de cada personaje pasó muy a menudo. También proporcionaron un método que verificaba los casos en que la posición de la pantalla no se verificaba antes de la llamada.

Por lo tanto, si puede verificar en un nivel alto y evitar los controles en el nivel bajo, puede acelerar las cosas significativamente.

En el caso que proporcione, si el código está en un bucle o si hay muchas declaraciones de registro, habrá un beneficio claro, ya que:

  • eliminar la creación de cadena (y el GC asociado)
  • reduce el número de sentencias if (aunque es muy probable que hotspote las optimice).

Yo diría que, en general, no debe agregar nada que se sepa que es costoso si hay una solución fácil. Esto claramente cae en ese caso: la adición de la declaración if no es difícil de hacer, es un dolor para poner más tarde y proporciona una mejora de velocidad / memoria definida.

Creo que la diferencia entre esto y la optimización prematura es que se sabe que esto siempre es costoso, por lo que el problema se reduce a: ¿es un costo acumulativo que desea agregar al programa o no? El costo es bastante constante y se conoce en el momento de escribir el código.


Si ya se conoce el "modelo", simplemente el registro no es tan costoso. Pero, si el "modelo" se debe buscar solo para el registro como se muestra a continuación, la simplicidad puede verse comprometida.

LOGGER.debug("model[" + proxy.getModel() + "]");