2008-08-28 7 views
13

¿Es posible que el compilador elimine los enunciados utilizados para la depuración (como el registro) del código de producción? Las declaraciones de depuración deberían marcarse de alguna manera, tal vez utilizando anotaciones.Cómo eliminar las instrucciones de depuración del código de producción en Java

Es fácil establecer una propiedad (debug = true) y verificarla en cada instrucción de depuración, pero esto puede reducir el rendimiento. Sería bueno si el compilador simplemente hiciera desaparecer las declaraciones de depuración.

Respuesta

22

Dos recomendaciones.

Primero: para el registro de bienes, use un paquete de registro moderno como log4j o del propio construido en el registro de Java. No se preocupe tanto por el rendimiento, la verificación del nivel de registro es del orden de nanosegundos. (es una comparación entera).

Y si tiene más de una sola declaración de registro, guarda todo el bloque:

(log4j, por ejemplo :)

if (logger.isDebugEnabled()) { 

    // perform expensive operations 
    // build string to log 

    logger.debug("...."); 
} 

Esto le da la tala de control de capacidad adicional en tiempo de ejecución. Tener que reiniciar y ejecutar una compilación de depuración puede ser muy inconveniente.

Segundo:

Usted puede encontrar assertions son más lo necesita. Una afirmación es una declaración que se evalúa como un resultado booleano, con un mensaje opcional:

assert (sky.state != FALLING) : "The sky is falling!"; 

Siempre que los resultados de afirmación en una falsa, la afirmación falla y hay un AssertionError se lanza que contiene el mensaje (esto es una excepción no comprobada, destinado a salir de la aplicación).

Lo bueno es que la JVM los trata de manera especial y puede alternarlos en tiempo de ejecución hasta el nivel de clase, utilizando un parámetro VM (no es necesario volver a compilar). Si no está habilitado, no hay gastos generales.

+0

Así es cómo habilitar las aserciones en Eclipse: [link] (http://www.coderanch.com/t/416987/vc/enable-Assertions-eclipse) –

+0

Esto no es una respuesta. No explica cómo hacer que las declaraciones 'desaparezcan' para el compilador (por lo tanto, no son visibles en el archivo de clase). ¿Tienes algo de información sobre eso? –

10
public abstract class Config 
{ 
    public static final boolean ENABLELOGGING = true; 
} 

import static Config.*; 

public class MyClass 
{ 
    public myMethod() 
    { 
     System.out.println("Hello, non-logging world"); 

     if (ENABLELOGGING) 
     { 
      log("Hello, logging world."); 
     } 
    } 
} 

El compilador se retire el bloque de código con "Hola, mundo el registro." en él si ENABLE_LOGGING se establece en verdadero porque es un valor final estático. Si usas un ofuscador como proguard, la clase Config también desaparecerá.

Un ofuscador también permitiría este tipo de cosas en su lugar:

public class MyClass 
{ 
    public myMethod() 
    { 
     System.out.println("Hello, non-logging world"); 

     Log.log("Hello, logging world."); 
    } 
} 

import static Config.*; 

public abstract class Log 
{ 
    public static void log(String s) 
    { 
     if (ENABLELOGGING) 
     { 
      log(s); 
     } 
    } 
} 

El método de registro # registro reduciría a nada en el compilador, y ser eliminado por el ofuscador, junto con cualquier llama a ese método y eventualmente incluso la clase Log se eliminaría.

0

Java contiene algún tipo de preprocesador propio. Se llama APT. Procesa y genera código. Por el momento no estoy seguro de cómo debería funcionar esto (no lo he probado). Pero parece ser usado para este tipo de cosas.

-2

Para responder directamente a su pregunta: No lo sé.

Pero aquí hay otra solución a su problema: En mi opinión, hay dos declaraciones que colisionan entre sí aquí: "instrucciones de depuración" y "código de producción".

¿Cuál es el propósito de las instrucciones de depuración? Ayuda para deshacerse de errores mientras se realizan las pruebas (de la unidad). Si una pieza de software se prueba adecuadamente y funciona de acuerdo con los requisitos, las instrucciones de depuración no son más que OBSOLETO.

Estoy totalmente en desacuerdo con dejar cualquier declaración de depuración en el código de producción. Apuesto a que nadie se molesta en probar los efectos secundarios del código de depuración en el código de producción. El código probablemente hace lo que se supone que debe hacer, pero ¿hace más que eso? ¿Funcionan correctamente todas sus #defines y realmente eliminan TODO el código de depuración? ¿Quién analiza 100000 líneas de código preprocesado para ver si todas las cosas de depuración han desaparecido?

A menos que tengamos una definición diferente de código de producción, debería considerar extraer las instrucciones de depuración una vez que se haya probado el código y que se haya terminado con él.

+3

Las sentencias de depuración en el código de producción pueden salvar la vida si tiene que depurar un sistema de producción (sin depurador). Y el software nunca se "prueba adecuadamente y funciona", se acerca cada vez más ... – sleske

+0

¿Desea borrar posiblemente cientos de declaraciones de depuración? Y luego agrégalos cuando continúes el desarrollo? Lo siento, pero esta es la razón por la cual se inventó #DEFINE en primer lugar. También esto es Java, no C. ¿Por qué responder una pregunta si no sabes? – Lodewijk

0

También recomendaría encarecidamente utilizar un marco de trabajo de registro.

El logger.IsDebugEnabled() no es obligatorio, simplemente es que puede ser más rápido comprobar si el sistema está en el nivel de depuración antes de iniciar sesión.

El uso de un marco de registro significa que puede configurar los niveles de registro sobre la marcha sin reiniciar la aplicación.

Usted podría tener el registro como:

logger.error("Something bad happened") 
logger.debug("Something bad happend with loads more detail") 
1

Otra posibilidad es poner la sentencia if dentro de su función de registro, se obtiene menos código de esta manera, pero a expensas de algunas llamadas a funciones adicionales.

Tampoco soy un gran admirador de eliminar completamente el código de depuración. Una vez que esté en producción, probablemente necesite acceder a los mensajes de depuración si algo sale mal. Si elimina toda la depuración del nivel de código, entonces esto no es una posibilidad.

0

Este "trick" parece tener sus instrucciones de depuración desaparecieron

public static final boolean DEBUG = false; 

if (DEBUG) { //disapeared on compilation } 

El post dijo que javac es lo suficientemente inteligente como para comprobar la static final boolean y excluir a las instrucciones de depuración. (I personalmente no probamos)

Para el registro, yo personalmente nose como para ver el código como:

if (logger.isDebugEnabled()) { 
    logger.debug("...."); 
} 
realImportantWork(); 

Las cosas de registro me distrae de la realImportantWork(). La forma correcta para mí es:

logger.debug("...."); 
realImportantWork() 

más la configuración que excluye todos los mensajes de depuración en la producción.

Quiero decir que el control logger.isDebugEnabled() debe ser el trabajo del marco de trabajo de registro, no es mi trabajo. La mayoría de los conceptos de soporte del marco de registro como "registrador", "LogLevel" ... que puede hacer el truco.

Cuestiones relacionadas