11

I need to obtain the computation time of some parts of an algorithm I have implemented in C with NDK/JNI.

I've read this question: Android Get Current timestamp?

I think I can obtain the computation time of a JNI call using the same method in this way:

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

But I need to check the computation times of some small parts inside the native method. How can I do it?

Community
  • 1
  • 1
Alessandro Gaietta
  • 547
  • 2
  • 8
  • 20
  • u can do it by setting log messages before and after the calling method...and then just use time = end - start; I mean print the time in log messages. – TheFlash Jun 19 '13 at 10:24
  • @AllessandroGaietta your example divides `currentTimeMillis()` by 1000... did you want your measurement to be as course as seconds? – mah Jun 19 '13 at 10:42
  • @mah It is a copy error, i don't want divide by 1000 ;D – Alessandro Gaietta Jun 19 '13 at 16:59
  • @Pratik obviously In the example there is the Log printing. I want to know how to use some similar function INSIDE the JNI call, to obtain the current time and print it in the log (i know how to print Log messages inside the JNI, just don't know how to get the time). – Alessandro Gaietta Jun 19 '13 at 17:01

2 Answers2

16

It's best not to use gettimeofday() or currentTimeMillis() on a mobile device. These return "wall clock" time, which can jump forward or backward suddenly if the network updates the time.

Use the monotonic clock instead for performance measurements -- System.nanoTime() or clock_gettime() with CLOCK_MONOTONIC. Note this returns a struct timespec rather than a struct timeval; primary difference is that the clock resolution is nanoseconds rather than microseconds.

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

In addition to wall-clock time you may be interested in per-thread CPU time; see Thread Performance in Android.

Community
  • 1
  • 1
fadden
  • 48,613
  • 5
  • 104
  • 152
  • How frequently is the wall clock time updated? I obtain very different time values between gettimeofday() and clock_gettime(CLOCK_PROCESS_CPUTIME_ID) methods. The second one seems more stable, but it's result is a larger time then the first one, instead I expected a smaller time! – Alessandro Gaietta Jun 28 '13 at 09:10
  • 1
    You can tell how often the wall clock timer is updated by calling it as fast as you can in a loop and subtracting the results the first time the value changes. It varies from device to device and release to release. The PROCESS_CPUTIME clock only advances when your process does work; if it's asleep, the clock doesn't change. (I'd recommend CLOCK_THREAD_CPUTIME_ID for performance work, since it only advances when the current thread uses the CPU.) The clocks are not tied to each other, and may not start at zero. – fadden Jun 28 '13 at 14:35
  • What I mean is that by measuring with clock_gettime(CLOCK_PROCESS_CPUTIME_ID) (or THREAD, same results) on a small set of operations (a few milliseconds) I get a time equal to gettimeofday() or a simple clock(). Instead, in long cycles I get a longer time with the first one, and the same, shorter, time with gettimeofday() and clock(). NOTE: in all cases I measure time between an end point and a start point, the result of clock_gettime() is corrected if nanoseconds difference < 0 (seconds++). clock() is translated dividing by CLOCKS_PER_SEC. – Alessandro Gaietta Jun 28 '13 at 22:52
  • Does the process/thread cpu time include the time that the processor was executing kernel-space instructions, on behalf of the program? Or are they excluded? – Paschalis May 31 '14 at 16:02
7

From within your 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));
}

This will get you a structure with the current time in seconds and microseconds, giving you enough to measure time between two points fairly easily. It then performs the conversion to return the current time, in milliseconds.

Edit: updated per @ChrisStratton's suggestion.

mah
  • 37,085
  • 9
  • 70
  • 91
  • This would be a more complete answer if you showed the conversion from the struct to a single milliseconds or microseconds value in a 64-bit type... – Chris Stratton Jun 19 '13 at 19:02
  • 1
    I have litle problem with types add L to numbers eg. struct timeval stCurrentTime; gettimeofday(&stCurrentTime, nullptr); return ((long long)stCurrentTime.tv_sec * 1000L) + ((long long)stCurrentTime.tv_usec / 1000L); //millseconds – Dawid Drozd Oct 28 '13 at 12:14