forma eficiente de poner declaraciones de depuración / registro en el código, para que no influyan en el tiempo de ejecución

In C-derivative languages there is the possibility to have conditional code for debug and runtime. That way there is no overhead left in the runtime.

How would I do this with Java/Android and the Log.i statements? If I just use a constant global boolean debugOn that obviously leaves the redundant checks in the runtime.

What is the best approach for conditional Log-statements?

Muchas gracias

EDIT:

Since there are quite some comments following the accepted answer I post my conclusion here....

private static final boolean DEBUG = true;

if (DEBUG) Log.i("xxx",this.getClass().getName()+ "->" + Thread.currentThread().getStackTrace()[2].getMethodName() );

...just like in xCode :)

preguntado el 08 de noviembre de 11 a las 13:11

3 Respuestas

Android build system started providing a constant BuildConfig.DEBUG some time ago, so I suggest using it and writing the code like this:

if (BuildConfig.DEBUG) Log.i(TAG, "Message");

No redundant checks will be made since it's a constant. This code will be optimized even by compiler, but you also have ProGuard at your disposal. Even if the checks are in place, any possible impact on performance should be negligible.

This approach used to have one drawback that you had to edit this constant yourself, either manually or through a custom rule in the build file. Now, however, this is handled automatically by the build system, so you don't have to do anything yourself.

Respondido 23 Jul 13, 12:07

How is that any better than Log.d(...)? And there's already Log.isLoggable(...). - Dave Newton

yes, but this will remain in the code even at runtime. Isn't there a more efficient way so that runtime remains lean somehow? - user387184

@user387184 No; Java doesn't have the equivalent of #ifdef, unless you implement it yourself. - Dave Newton

if DEBUG is declared static and final then the compiler will inline the value and omit the bytecode for the log statements, so its effectively working as an #ifdef - Jacob Nordfalk

@Elemental Yes, the compiler will should remove the dead code, and even if it doesn't, then ProGuard definitely will. ProGuard doesn't just obfuscate, it also shrinks code and makes a lot of optimizations, which include elimination of dead code branches. - Malcolm

Create your own Log class by by extending Log class , create static variable debugLevel inside it , create your own methods and labels like INFO, DEBUG ect .

now change in value of static varable debugLevel , will reflect to whole application.

so no need for if(debug) everywhere .

respondido 08 nov., 11:17

It would still (a) construct the string log message, and (b) call the log class to check the value. - Dave Newton

Java doesn't have C-like conditional compilation, unless you implement it yourself. (It's not all that difficult, but IMO it's not worth the trouble.)

Your options are pretty limited. The best you can do is wrap expensive logging statements in an isLoggable.

if (Log.isLoggable(tag, Log.DEBUG)) {
    Log.d(tag, expensiveStringGeneration());
}

For short log statements, it's more noise than it's worth.

Editar Malcolm might be right (although I still wouldn't bother, in all likelihood.)

Editar The comparison to a static DEBUG is still in the byte code; ProGuard should remove it the unnecessary branch. Without ProGuard, it would be up to the JIT, or the compiler implementation.

respondido 08 nov., 11:17

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.