开发者

Rudimentary ways to measure execution time of a method

开发者 https://www.devze.com 2022-12-09 02:31 出处:网络
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?

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 timeI开发者_JS百科ntervalSinceDate 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?


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;


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.


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.


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.


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.


I will repost my answer from another post here. Note that my admittedly simple solution to this complex problem uses NSDate and NSTimeInterval as its foundation:


I know this is an old one but even I found myself wandering past it again, so I thought I'd submit my own option here.

Best bet is to check out my blog post on this: Timing things in Objective-C: A stopwatch

Basically, I wrote a class that does stop watching in a very basic way but is encapsulated so that you only need to do the following:

[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];

And you end up with:

MyApp[4090:15203]  -> Stopwatch: [My Timer] runtime: [0.029]

in the log...

Again, check out my post for a little more or download it here: MMStopwatch.zip


@bladnman I love your stopwatch thing.. I use it all the time.. Here's a little block I wrote that eliminates the need for the closing call, and makes it even EASIER (if that even seemed possible) to use, lol.

+(void)stopwatch:(NSString*)name timing:(void(^)())block {
    [MMStopwatch start:name];
    block();
    [MMStopwatch stop: name];
}

then you can just call it wherever..

[MMStopwatch stopwatch:@"slowAssFunction" timing:^{
    NSLog(@"%@",@"someLongAssFunction");
}]; 

someLongAssFunction

-> Stopwatch: [slowAssFunction] runtime:[0.054435]

You should post that sucker to github - so people can find it easily / contribute, etc. it's great. thanks.

0

精彩评论

暂无评论...
验证码 换一张
取 消