tags:

views:

310

answers:

5

What object/method would I call to get current time in milliseconds (or great precision) to help measure how long a method took to execute?

NSDate's timeIntervalSinceDate will return NSInterval which is measured in seconds. I am looking for something finer grained, something similar to Java's System.currentTimeMillis.

Is there an equivalent version in objective-c/CocoaTouch?

+5  A: 

Actually, +[NSDate timeIntervalSinceReferenceDate] returns an NSTimeInterval, which is a typedef for a double. The docs say

NSTimeInterval is always specified in seconds; it yields sub-millisecond precision over a range of 10,000 years.

So it's safe to use for millisecond-precision timing. I do so all the time.

Dave DeLong
thank-you -- I misread the documentation.
Alexi Groove
You loose a lot of time just calling `timeIntervalSinceReferenceDate`, this biases the result in an unpredictable way.
Georg
+2  A: 

timeIntervalSinceReferenceDate is perfectly fine.

However, unless it's a long-running method, this won't bear much fruit. Execution times can vary wildly when you're talking about a few millisecond executions. If your thread/process gets preempted mid-way through, you'll have non-deterministic spikes. Essentially, your sample size is too small. Either use a profiler or run 100,000 iterations to get total time and divide by 100,000 to get average run-time.

Bob Aman
+6  A: 

For very fine-grained timings on OS X, I use mach_absolute_time( ), which is defined in <mach/mach_time.h>. You can use it as follows:

#include <mach/mach_time.h>
#include <stdint.h>

static double ticksToNanoseconds = 0.0;

uint64_t startTime = mach_absolute_time( );
// Do some stuff you want to time here
uint64_t endTime = mach_absolute_time( );

 // Elapsed time in mach time units
uint64_t elapsedTime = endTime - startTime;

// The first time we get here, ask the system
// how to convert mach time units to nanoseconds
if (0.0 == ticksToNanoseconds) {
    mach_timebase_info_data_t timebase;
    // to be completely pedantic, check the return code of this next call.
    mach_timebase_info(&timebase);
    ticksToNanoseconds = (double)timebase.numer / timebase.denom;
}

double elapsedTimeInNanoseconds = elapsedTime * ticksToNanoseconds;
Stephen Canon
+1  A: 

If you're trying to tune your code's performance, you would do better to use Instruments or Shark to get an overall picture of where your app is spending its time.

NSResponder
+1  A: 

Do not use NSDate for this. You're loosing a lot of precision to call methods and instantiate objects, maybe even releasing something internal. You just don't have enough control.

Use either time.h or as Stephen Canon suggested mach/mach_time.h. They are both much more accurate.

The best way to do this is to fire up Instruments or Shark, attach them to your process (works even if it's already running) and let them measure the time a method takes.

After you're familiar with it this takes even less time than any put-in-mach-time-functions-and-recompile-the-whole-application solution. You even get a lot of information extra. I wouldn't settle for anything less.

Georg