Objective-C
time measurement
programming
code performance
development tips

Getting time elapsed in Objective-C

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Measuring elapsed time in Objective-C is a common task when profiling code, timing network work, or logging how long a user-visible action takes. The right API depends on what you are measuring: coarse wall-clock duration, animation timing, or very small performance-critical intervals.

Objective-C projects on Apple platforms have several good options. The most practical ones are CFAbsoluteTimeGetCurrent, NSDate, and lower-level Mach timing functions for higher precision.

Measuring General-Purpose Elapsed Time

For most application code, CFAbsoluteTimeGetCurrent is a solid default. It returns a floating-point number representing the current absolute time in seconds, which makes subtraction simple and easy to read.

objective-c
1#import <Foundation/Foundation.h>
2#import <CoreFoundation/CoreFoundation.h>
3
4static void runTimedTask(void) {
5    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
6
7    NSMutableArray *values = [NSMutableArray array];
8    for (NSInteger i = 0; i < 100000; i++) {
9        [values addObject:@(i)];
10    }
11
12    CFAbsoluteTime elapsed = CFAbsoluteTimeGetCurrent() - start;
13    NSLog(@"Elapsed time: %.6f seconds", elapsed);
14}
15
16int main(int argc, const char * argv[]) {
17    @autoreleasepool {
18        runTimedTask();
19    }
20    return 0;
21}

This approach is easy to drop into an existing method and is accurate enough for many app-level measurements.

Using NSDate for Readable Application Code

NSDate can do the same job and reads well in high-level Objective-C code, especially if you are already working with Foundation objects.

objective-c
1NSDate *startDate = [NSDate date];
2
3// Work to measure goes here.
4[NSThread sleepForTimeInterval:0.25];
5
6NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceDate:startDate];
7NSLog(@"Elapsed time: %.3f seconds", elapsed);

NSDate is convenient, but it is still a wall-clock style measurement. For benchmarking tiny sections of code, you usually want something with lower overhead and finer resolution.

High-Precision Timing with Mach

For short operations, mach_absolute_time is the classic low-level choice. It returns a hardware-dependent tick count, which you then convert to nanoseconds using mach_timebase_info.

objective-c
1#import <Foundation/Foundation.h>
2#import <mach/mach_time.h>
3
4static double elapsedMilliseconds(uint64_t start, uint64_t end) {
5    mach_timebase_info_data_t info;
6    mach_timebase_info(&info);
7
8    uint64_t elapsed = end - start;
9    double nanos = (double)elapsed * (double)info.numer / (double)info.denom;
10    return nanos / 1000000.0;
11}
12
13static void benchmarkLoop(void) {
14    uint64_t start = mach_absolute_time();
15
16    volatile NSInteger total = 0;
17    for (NSInteger i = 0; i < 1000000; i++) {
18        total += i;
19    }
20
21    uint64_t end = mach_absolute_time();
22    NSLog(@"Loop took %.3f ms", elapsedMilliseconds(start, end));
23}

This is a better fit for microbenchmarks because it measures a monotonic clock source rather than user-visible wall time.

Choosing the Right Tool

Use CFAbsoluteTimeGetCurrent when you want a straightforward elapsed-time measurement in regular app code. It is simple, readable, and does not require any conversion math.

Use NSDate when you are already in Foundation-heavy code and the measurement is coarse enough that object creation overhead does not matter.

Use mach_absolute_time when you need higher precision or a monotonic time source for very short operations. It is more verbose, but it avoids some of the noise that affects wall-clock timing.

There is also CACurrentMediaTime from QuartzCore, which is convenient in animation-heavy code, but the three approaches above cover most Objective-C timing tasks.

Getting Better Benchmark Numbers

A single timing run is often misleading. Background work, cache warmup, and debug builds can all distort the result. For more reliable numbers:

  • Measure code in release builds when possible
  • Run the same code several times
  • Ignore the first run if setup costs dominate
  • Keep logging outside the measured section

A small helper can make repeated measurement easier:

objective-c
1double total = 0.0;
2
3for (NSInteger run = 0; run < 5; run++) {
4    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
5
6    // Call the method under test here.
7    [NSThread sleepForTimeInterval:0.01];
8
9    total += CFAbsoluteTimeGetCurrent() - start;
10}
11
12NSLog(@"Average: %.6f seconds", total / 5.0);

This does not replace a dedicated profiler, but it is often enough for targeted performance checks.

Common Pitfalls

One frequent mistake is using wall-clock APIs to benchmark extremely small code paths and then trusting the result too much. The timing noise can be larger than the operation itself.

Another issue is measuring debug builds and concluding that the production code is slow. Compiler optimizations can change performance dramatically.

Logging inside the measured block is also misleading because NSLog is relatively expensive. Time the work, then log afterward.

Finally, make sure the compiler cannot optimize away the work you are trying to measure. In microbenchmarks, unused results may disappear entirely unless you keep a visible side effect.

Summary

  • 'CFAbsoluteTimeGetCurrent is a practical default for elapsed time in Objective-C.'
  • 'NSDate is readable and convenient for high-level application timing.'
  • 'mach_absolute_time is better for short, high-precision measurements.'
  • Reliable benchmarking requires repeated runs, release builds, and careful isolation of the measured code.
  • The best timing API depends on whether you care about readability, monotonic behavior, or precision.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.