2009-03-17 15 views
18

Nuestro equipo tiene la política de no hacer el registro comoEncerrar llamadas a debug() en if isDebugEnabled(): ¿una buena política?

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

en lugar de simplemente llamando al método de registro de la siguiente manera:

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

Esta práctica es capaz de conducir a algunos performance improvement, pero por otra parte hace que la base de código sea más compleja. 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 debe usarse cada vez que estamos haciendo un registro.

¿Crees que es una buena política?

Respuesta

7

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

La primera regla de la optimización del Programa: No practico.

La segunda regla de la optimización de programas: solo para expertos: no lo hagas todavía.

Creo que en la mayoría de los casos no vale la pena hacer que la base de código sea más compleja 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 adicionales de código en un caso particular. En la mayoría de los casos, las líneas adicionales solo agregan complejidad sin ninguna ganancia notable en el lado del rendimiento.

+1

Es obvio que si el autor ha hecho esta pregunta, entonces es una llamada para que realice la optimización. Es decir. cuando se le pide que optimice un fragmento de código, no responde con las dos citas anteriores. Comprenda de dónde viene, pero no ayuda en esta situación. –

+0

-1 de mí. odio este mantra de "no hacer la optimización". Tiene graves fallas: si su optimización * arrojará resultados (incluso trivalmente) y es casi * libre * para eso (ya que esto es así, las instrucciones 'si' son triviales) y no es complicado (y está envolviendo una declaración de registro) en un si es solo el más trivial) entonces solo adelante y hazlo. – bharal

+1

No estoy de acuerdo, esto está en la línea de una actividad de lista de verificación para evitar problemas, que puede comunicarse fácilmente a un desarrollador junior, para que no introduzca un error por accidente que alguien tenga que pasar el tiempo depurando más tarde. – ammianus

16

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

  • Una gran cantidad de trabajo que hay que entrar en la construcción de la cadena (por ejemplo, se tiene que realizar búsquedas, o construir una gran cadena a partir de un montón de piezas muy pequeñas)
  • Está en un bucle que no está haciendo mucho otro trabajo (pero que se llama muy a menudo), por lo que la proporción del tiempo dedicado a la construcción de incluso una cadena sencilla de registro es mayor

no debería ser una regla manta , y espero que ambas situaciones sean relativamente poco frecuentes.

Por supuesto, lo que realmente queremos es ser capaz de decir: "Llame al método de depuración, que pasa en una alegación que no es la cadena de depuración en sí, 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, capturar las variables relevantes podría ser significativo en algunas situaciones, dependiendo de cómo maneja la lengua la captura.)

+2

¿SLF no tiene opciones de formato de cadena en sus métodos de registro? –

+0

Siempre defiendo usar esta regla siempre, porque el desarrollador no necesita pensar en los costos de construir la cadena (parámetros). A veces, es necesario crear parámetros adicionales para el registro de depuración, como 'getEntryDebugString()'. Es mejor tener algunas líneas más y código propenso a errores que lamentarlo por problemas poco frecuentes. – xmedeko

0

Si ya se conoce el "modelo", simplemente inicie sesión no es tan caro Pero, si el "modelo" debe buscarse solo para iniciar sesión como se muestra a continuación, la simplicidad puede verse comprometida.

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

creo que tiene sence para poner la llamada isDebugEnabled() antes de escribir su mensaje de registro. Luego puede actualizar fácilmente su mensaje de registro. Utilizamos 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 tenga la instrucción if perderá tiempo. Recuerde ... su proyecto se vuelve más grande y sus mensajes de registro también.

¡Los mensajes de registro no deberían ralentizar su código!

+2

Existe una alternativa muy conveniente basada en formatos de mensaje: mensajes parametrizados. http://www.slf4j.org/faq.html#logging_performance – pisaruk

21

Debe utilizar SLF4J y hacer log4j su aplicación. Con SLF4J, puede eliminar isDebugEnabled() por completo mediante el uso de mensajes parametrizados.

Ver las section about logging performance in the slf4j FAQ

Los siguientes dos líneas producirán la misma salida exacta. Sin embargo, el segundo formulario superará al primer formulario por un factor de al menos 30, en el caso de una declaración de anotación deshabilitada.

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

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

+1

El formato de cadena no ayuda cuando un parámetro que construye 'entry' es costoso. P.ej. Considere algunos 'logger.debug (" La nueva entrada es {}. ", getEntry());' y usted no sabe qué tan costoso es 'getEntry()'. – xmedeko

2

No puedo encontrar la referencia en línea (tal vez lo leí en un libro), pero no fue un ejemplo de que algunos llaman BIOS que escribió una cadena a la pantalla.

El código que escribió la secuencia de la pantalla se comprobó 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 verificó para asegurarse de que el carácter no se borre de la pantalla.

Al eliminar el código de comprobación de la función que escribió el carácter en la pantalla, se obtuvo un impulso de velocidad masivo. El era porque la impresión de cada personaje sucedía muy a menudo. También proporcionaron un método que verificaba los casos en los que la posición de la pantalla no estaba marcada antes de la llamada.

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

En el caso que nos proporcione, si el código está en un bucle o si hay una gran cantidad de declaraciones de registro entonces no sería un claro beneficio, ya que lo haría:

  • retire la creación cadena (y el GC asociado)
  • reducen la cantidad de sentencias if (aunque es muy probable que hotspote las optimice).

Yo diría que, en general, no debería agregar nada que se sabe que es costoso si hay un trabajo fácil. Claramente, esto cae en ese caso: la adición de la declaración if no es difícil de hacer, es un dolor incluirla más tarde, y proporciona una mejora definida de velocidad/memoria.

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

Cuestiones relacionadas