Pregunta

¿Es posible que el compilador elimine las declaraciones utilizadas con fines de depuración (como el registro) del código de producción?Las declaraciones de depuración deberían marcarse de alguna manera, tal vez usando anotaciones.

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

¿Fue útil?

Solución

Dos recomendaciones.

Primero:para un registro real, utilice un paquete de registro moderno como log4j o el registro integrado 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 de números enteros).

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

(log4j, por ejemplo :)

if (logger.isDebugEnabled()) {

  // perform expensive operations
  // build string to log

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

Esto le brinda la capacidad adicional de controlar el registro en tiempo de ejecución.Tener que reiniciar y ejecutar una compilación de depuración puede resultar muy inconveniente.

Segundo:

Puedes encontrar afirmaciones son más lo que necesitas.Una aserció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 la afirmación resulta falsa, la afirmación falla y se genera un AssertionError que contiene su mensaje (esta es una excepción no marcada, destinada a salir de la aplicación).

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

Otros consejos

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 eliminará el bloque de código con "Hello, Registro World". En él, si habilita_logging se establece en True porque es un valor final estático.Si utiliza un ofuscador como proguard, la clase Config también desaparecerá.

Un ofuscador también permitiría cosas como esta:

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 Log#log se reduciría a nada en el compilador y el ofuscador lo eliminaría, junto con cualquier llamada a ese método y, finalmente, incluso la clase Log se eliminaría.

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

Tampoco soy un gran partidario de eliminar por completo el código de depuración.Una vez que esté en producción, probablemente necesitará acceso a mensajes de depuración si algo sale mal.Si elimina toda la depuración a nivel de código, esto no es una posibilidad.

Usar Preprocesador Java?(google foo low pero este es un enlace a los antiguos foros de Joel que lo discuten)

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

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

El logger.IsDebugEnabled() No es obligatorio, simplemente puede ser más rápido verificar 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.

Podrías tener un registro como:

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

Este "truco"parece hacer que sus declaraciones de depuración desaparezcan

public static final boolean DEBUG = false;

if (DEBUG) { //disapeared on compilation }

El correo dijo eso javac es lo suficientemente inteligente como para comprobar el static final boolean y excluir las declaraciones de depuración.(Yo personalmente no lo probé)

Para iniciar sesión, personalmente no me gusta ver códigos como:

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

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

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

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

Quiero decir que el logger.isDebugEnabled() El control debería ser trabajo del marco de registro, no mi trabajo.La mayoría de los marcos de registro admiten conceptos como "logger", "LogLevel".que puede hacer el truco.

Para responder directamente a su pregunta:No sé.

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

¿Cuál es el propósito de las declaraciones de depuración?Ayude a deshacerse de errores durante las pruebas (unitarias).Si una pieza de software se prueba adecuadamente y funciona de acuerdo con los requisitos, las declaraciones de depuración no son más que OBSOLETAS.

Estoy totalmente en desacuerdo con dejar declaraciones 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?¿Todos tus #defines funcionan correctamente y realmente eliminan TODO el código de depuración?¿Quién analiza 100.000 líneas de código preprocesado para ver si todo el material de depuración ha desaparecido?

A menos que tengamos una definición diferente de código de producción, debería considerar eliminar las declaraciones de depuración después de probar el código y terminar con ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top