2013-06-19 8 views
9

Ich brauche die Rechenzeit einiger Teile eines Algorithmus, den ich in C mit NDK/JNI implementiert habe.Wie bekomme ich Rechenzeit in NDK?

ich diese Frage gelesen habe: Android Get Current timestamp?

Ich glaube, ich kann die Rechenzeit eines JNI Aufruf mit der gleichen Methode auf diese Weise erhalten:

Long start, end, time; 
start = System.currentTimeMillis()/1000; 
//my native call 
end = System.currentTimeMillis()/1000; 
time = end - start; 
Log.i(TAG, "Time ... (ms): " + time); 

Aber ich brauche die Berechnung zu überprüfen Zeiten von einigen kleinen Teilen innerhalb der nativen Methode. Wie kann ich es tun?

+0

Sie können dies tun, indem Sie Protokollnachrichten vor und nach der aufrufenden Methode festlegen ... und dann einfach time = end - start; Ich meine, drucke die Zeit in Log-Nachrichten. – TheFlash

+0

@AllessandroGaietta Ihr Beispiel teilt 'currentTimeMillis()' mit 1000 ... wollten Sie, dass Ihre Messung so schnell wie Sekunden ist? – mah

+0

@mah Es ist ein Kopierfehler, ich will nicht durch 1000 dividieren; D –

Antwort

7

aus Ihrem C/C++ Code,

#include <sys/time.h> 
long long currentTimeInMilliseconds() 
{ 
    struct timeval tv; 
    gettimeofday(&tv, NULL); 
    return ((tv.tv_sec * 1000) + (tv.tv_usec/1000)); 
} 

Diese Ihnen eine Struktur mit der aktuellen Zeit in Sekunden und Mikrosekunden erhalten, so dass Sie genügend Zeit zwischen zwei Punkten ziemlich leicht zu messen. Es führt dann die Konvertierung durch, um die aktuelle Zeit in Millisekunden zurückzugeben.

Bearbeiten: aktualisiert per @ ChrisStrattons Vorschlag.

+0

Dies wäre eine vollständigere Antwort, wenn Sie die Umwandlung von der Struktur zu einem einzelnen Millisekunden oder Mikrosekunden Wert in einem 64-Bit-Typ gezeigt ... –

+0

@ChrisStratton nice suggestion; bearbeitet. – mah

+1

Ich habe ein kleines Problem mit Typen hinzufügen L zu Zahlen zB. struct timeval stCurrentTime; gettimeofday (& stCurrentTime, nullptr); return ((lang lang) stCurrentTime.tv_sec * 1000L) + ((lang lang) stCurrentTime.tv_usec/1000L); // Millisekunden –

12

Es ist am besten, nicht gettimeofday() oder currentTimeMillis() auf einem mobilen Gerät zu verwenden. Diese geben die "Wanduhr" -Zeit zurück, die plötzlich vorwärts oder rückwärts springen kann, wenn das Netzwerk die Zeit aktualisiert.

Verwenden Sie stattdessen die monotone Uhr für Leistungsmessungen - System.nanoTime() oder clock_gettime() mit CLOCK_MONOTONIC. Beachten Sie, dass dies eine struct timespec statt struct timeval zurückgibt; Der Hauptunterschied besteht darin, dass die Taktauflösung in Nanosekunden statt in Mikrosekunden liegt.

int64_t getTimeNsec() { 
    struct timespec now; 
    clock_gettime(CLOCK_MONOTONIC, &now); 
    return (int64_t) now.tv_sec*1000000000LL + now.tv_nsec; 
} 

Zusätzlich zur Wanduhrzeit können Sie sich für pro-thread CPU-Zeit interessieren; siehe Thread Performance in Android.

+0

Wie oft wird die Wanduhrzeit aktualisiert? Ich erhalte sehr unterschiedliche Zeitwerte zwischen den Methoden gettimeofday() und clock_gettime (CLOCK_PROCESS_CPUTIME_ID). Die zweite scheint stabiler zu sein, aber das Ergebnis ist eine größere Zeit als die erste, stattdessen habe ich eine kleinere Zeit erwartet! –

+1

Sie können feststellen, wie oft der Wanduhr-Timer aktualisiert wird, indem Sie ihn so schnell wie möglich in einer Schleife aufrufen und die Ergebnisse bei der ersten Änderung des Werts subtrahieren. Es variiert von Gerät zu Gerät und von Release zu Release. Die PROCESS_CPUTIME-Uhr wird nur dann aktualisiert, wenn Ihr Prozess funktioniert. Wenn es schläft, ändert sich die Uhr nicht. (Ich würde CLOCK_THREAD_CPUTIME_ID für die Performance-Arbeit empfehlen, da es nur fortschreitet, wenn der aktuelle Thread die CPU verwendet.) Die Uhren sind nicht miteinander verbunden und beginnen möglicherweise nicht bei Null. – fadden

+0

Was ich meine ist, dass durch Messen mit clock_gettime (CLOCK_PROCESS_CPUTIME_ID) (oder THREAD, gleiche Ergebnisse) auf einer kleinen Reihe von Operationen (ein paar Millisekunden) bekomme ich eine Zeit gleich gettimeofday() oder eine einfache Uhr(). Stattdessen bekomme ich in langen Zyklen eine längere Zeit mit der ersten und die gleiche, kürzere Zeit mit gettimeofday() und clock(). HINWEIS: In allen Fällen wird die Zeit zwischen einem Endpunkt und einem Startpunkt gemessen. Das Ergebnis von clock_gettime() wird korrigiert, wenn der Unterschied zwischen Nanosekunden <0 (Sekunden ++) ist. clock() wird übersetzt durch CLOCKS_PER_SEC. –