2010-06-27 22 views
34

¿Cuál es la ejecución de tiempo más fácil en Android?Ejecución del código de tiempo en Android

He mirado un poco y encontré TimingLogger en el SDK de Android, y las instrucciones here. Parece muy conveniente. Pero no puedo hacer que funcione. Este es mi código:

TimingLogger timings = new TimingLogger("TopicLogTag", "Parsing html"); 
    My code to time here... 
timings.dumpToLog(); 

Se supone que debe volcar los tiempos en LogCat. Pero no puedo ver nada ... I ¿Qué estoy haciendo mal? Eclipse no muestra ningún variado. Supongo que tiene algo con salida prolija, pero he configurado LogCat para que muestre Verbose. Gracias ..

Respuesta

56

lo di una prueba y estoy experimentando lo mismo. Todo se reduce a este poco de la descripción en el Javadoc for TimingLogger:

Si el Log.isLoggable no está activado a por lo menos el nivel de Log.VERBOSE esa etiqueta en el momento de la creación, entonces el addSplit y la llamada dumpToLog hará nada.

Hice una prueba a nivel local:

TimingLogger timings = new TimingLogger("MyTag", "Initialization"); 
Log.d("MyTag", "Is Loggable? " + Log.isLoggable("MyTag", Log.VERBOSE)); 
timings.dumpToLog(); 

Y curiosamente, me sale una salida para el registro:

06-28 08:35:18.693: DEBUG/MyTag(24366): Is Loggable? false 

Pero eso es todo. Y puesto que es falsa, no creo que TimingLogger está haciendo nada, basado en el TimingLogger code:

90  /** 
    91  * Clear and initialize a TimingLogger object that will log using 
    92  * the tag and label that was specified previously, either via 
    93  * the constructor or a call to reset(tag, label). If the 
    94  * Log.isLoggable is not enabled to at least the Log.VERBOSE 
    95  * level for that tag at creation time then the addSplit and 
    96  * dumpToLog call will do nothing. 
    97  */ 
    98  public void reset() { 
    99   mDisabled = !Log.isLoggable(mTag, Log.VERBOSE); 
100   if (mDisabled) return; 
101   if (mSplits == null) { 
102    mSplits = new ArrayList<Long>(); 
103    mSplitLabels = new ArrayList<String>(); 
104   } else { 
105    mSplits.clear(); 
106    mSplitLabels.clear(); 
107   } 
108   addSplit(null); 
109  } 

No estoy seguro de por qué Log.isLoggable vuelve falsa cuando es obvio que el registro por encima de VERBOSE, ya que mi Log.d, obviamente, registrado.

puede habilitar el registro para esa etiqueta manualmente desde el [Javadoc clase Log] [3]:

Puede cambiar el nivel de acceso predeterminado establecer una propiedad del sistema: 'setprop log.tag. 'Donde el nivel es VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT o SUPPRESS. SUPPRESS desactivará todos los registros para su etiqueta. También puede crear un archivo local.prop que con el siguiendo en él: 'log.tag.' = colocarlo en /data/local.prop.

cual hice a través adb shell:

$ adb shell 
# setprop 
usage: setprop <key> <value> 
# setprop log.tag.MyTag VERBOSE 
# 

Resultados: en

06-28 08:53:42.447: DEBUG/MyTag(24739): Is Loggable? true 
06-28 08:53:44.744: DEBUG/MyTag(24739): Initialization: begin 
06-28 08:53:44.744: DEBUG/MyTag(24739): Initialization: end, 0 ms 

Véase el comentario de droidgren en esta respuesta - al parecer una llamada a addSplit también es necesario.

[3]: http://developer.android.com/reference/android/util/Log.html#isLoggable(java.lang.String, int)

+3

¡Gracias, eso fue todo !. Pero necesita tener al menos un timesings.addSplit para hacer realidad la medición en cualquier momento. Y solo necesita hacer setprop una vez por etiqueta. ¡Genial! – droidgren

+1

VERBOSE está "por encima" de DEPURACIÓN para Android. – George

+1

@mbafford: Tal vez deberías actualizar la respuesta un poco para que uno sepa al leerla que uno tiene que llamar al método addSplit al menos una vez. – wojciii

0

Trate de hacer:

adb shell logcat 
+0

Voy a intentarlo, pero no veo por qué debería diferir de tener un panel de logcat en eclipse. – droidgren

+0

@droidgren: Por lo general, pruebo eso primero para asegurarme de que no haya ningún problema con el eclipse. – Macarse

9

he encontrado otra solución más sencilla que mide exactamente el mismo tiempo como TimingLogger, que no requiere setprop.

private long startnow; 
private long endnow; 

startnow = android.os.SystemClock.uptimeMillis(); 
*Your time consuming code here* 
endnow = android.os.SystemClock.uptimeMillis(); 
Log.d("MYTAG", "Execution time: " + (endnow - startnow) + " ms"); 
+3

Si usa java.lang.System.nanoTime() obtendrá el mismo reloj que uptimeMillis(), con una resolución (ligeramente) mejor, utilizando una llamada J2SE. Sin embargo, tenga en cuenta que TimingLogger usa el reloj elapsedRealtime() en su lugar (mantiene el tiempo en "sleep profundo"). – fadden

2

A veces no necesitamos saber el momento exacto en que nos llevó una operación, pero lo que queremos saber, ¿por qué esa operación tomó tanto tiempo. Por lo tanto, para acelerar el código, solo necesitamos saber algún tipo de orden relacional de partes de esa operación donde el que ocupa más tiempo parece ser el que debe optimizar. Por lo tanto, androide trae método de seguimiento:

Debug.startMethodTracing("YOUR_TRACE_FILE_NAME"); 

// Do your operations 

Debug.stopMethodTracing(); 

A continuación, el sistema operativo escribe el archivo de seguimiento que contiene todas las informaciones de llamadas a sistema de archivos. Simplemente arrastre y suelte ese archivo en traceview.bat y comience a inspeccionar qué llamadas tardaron en hacerlo.

Beneficios:

  • Puede inspeccionar todas las llamadas funciones y métodos que han sido llamados, mientras que el rastreo.
  • No es necesario sincronizar los datos para aplicaciones multiproceso.
  • Trace se escribe automáticamente en el archivo - sin log cat magic o lo que sea necesario. Todos los datos están encapsulados juntos, listos para ser inspeccionados.
  • Tan pronto como empiece a agregar la medición de tiempo y especialmente el registro, de todos modos destruirá el tiempo.

Enlace: http://developer.android.com/tools/debugging/debugging-tracing.html

+0

¡esto debería estar probablemente más arriba en el hilo! –

+0

¿Qué es "traceview.bat"? ¿Dónde lo consigo? –

8

Si ustedes miren su source code, en realidad la implementación de la clase TimingLogger es bastante simple.

Entonces lo que hice, lo que encaja perfectamente para mi caso de uso, era hacer mi propia versión de la clase pero cambiando el método reset() a

public void reset() { 
    mDisabled = false; // <- This is what has changed. 
    if (mDisabled) return; 
    if (mSplits == null) { 
     mSplits = new ArrayList<Long>(); 
     mSplitLabels = new ArrayList<String>(); 
    } else { 
     mSplits.clear(); 
     mSplitLabels.clear(); 
    } 
    addSplit(null); 
} 

El truco aquí está cambiando de

mDisabled = !Log.isLoggable(mTag, Log.VERBOSE);

a

mDisabled = false;

De esta manera no tenemos que meternos con adb.

+2

¡Buen hombre! Funciona – Tooto

3

Si simplemente busca los registros como se explica en developer.android.com, no podrá ver los registros.Así que utilice a continuación comando:

  1. adb shell setprop log.tag.MyTag VERBOSE

Nota: MyTag es el primer parámetro que ha pasado la hora de crear nuevos TimingLogger de la siguiente manera:

TimingLogger timings = new TimingLogger("MyTag", "MyMethodName");

Para sus de preguntas respuesta, debe ejecutar debajo del comando: adb shell setprop log.tag.TopicLogTag VERBOSE

Y ahí está. ¡Feliz codificación!

Cuestiones relacionadas