HOWTO · C

How to Use the gettimeofday Function in C

Learn how to measure elapsed and CPU time in C with gettimeofday, clock_gettime, and clock.

On this page

For elapsed time around a block of C code, prefer clock_gettime with CLOCK_MONOTONIC: it measures a duration without being affected by wall-clock adjustments. gettimeofday is a widely available legacy option that reports wall-clock time, while clock measures process CPU time. The examples below show the difference calculation and checked calls; their measured durations depend on the machine and build.

Measure Elapsed Time with gettimeofday

gettimeofday is declared by <sys/time.h> and fills a struct timeval. Its tv_sec field is seconds since the Epoch and tv_usec is the fractional part in microseconds. The timezone argument is obsolete; pass NULL. This API remains available on many Unix-like systems, but it is a legacy choice for interval timing because the wall clock can be adjusted.

The example records two readings around a loop and combines the seconds and microseconds differences in elapsed. A volatile accumulator makes the loop’s result observable so an optimizing compiler cannot discard the work. The loop runs from 0 through 9,999, so its sum, 49,995,000, fits even the minimum 32-bit range of unsigned long. Replace the loop with the operation you want to measure. The output includes both the work count and calculated elapsed duration. The timing value below is illustrative; it varies by system and build.

Run this example:

#include <stdio.h>
#include <sys/time.h>

int main(void) {
    struct timeval start, end;
    volatile unsigned long total = 0;

    if (gettimeofday(&start, NULL) != 0) {
        return 1;
    }
    for (unsigned long i = 0; i < 10000UL; ++i) {
        total += i;
    }
    if (gettimeofday(&end, NULL) != 0) {
        return 1;
    }

    double elapsed = (double)(end.tv_sec - start.tv_sec)
                   + (double)(end.tv_usec - start.tv_usec) / 1000000.0;
    printf("gettimeofday elapsed: %.6f seconds (work=%lu)\n", elapsed, total);
    return 0;
}

gettimeofday returns zero on success and a nonzero value on failure. Check both readings before using the structures. Because this is a wall-clock measurement, a system clock adjustment during the interval can affect the calculated difference. The displayed decimal places describe formatting, not guaranteed measurement resolution.

Measure Elapsed Time with clock_gettime

For elapsed intervals, use clock_gettime(CLOCK_MONOTONIC, ...). CLOCK_MONOTONIC advances monotonically and is not a calendar clock. CLOCK_REALTIME represents wall time and can change when the system clock is adjusted, so it is usually a poor choice for measuring durations. The function and struct timespec are declared in <time.h>; tv_sec holds seconds and tv_nsec holds nanoseconds. Nanosecond units do not promise nanosecond accuracy or actual clock resolution.

This complete example checks both calls and calculates the interval in seconds. Its 49,995,000 total fits the minimum 32-bit range of unsigned long; the output shows that work count and the calculated elapsed duration. The timing value below is illustrative because it varies by system and build. The feature-test macro requests the POSIX declaration for clock_gettime on systems that require it.

#define _POSIX_C_SOURCE 199309L
#include <stdio.h>
#include <time.h>

int main(void) {
    struct timespec start, end;
    volatile unsigned long total = 0;

    if (clock_gettime(CLOCK_MONOTONIC, &start) != 0) {
        return 1;
    }
    for (unsigned long i = 0; i < 10000UL; ++i) {
        total += i;
    }
    if (clock_gettime(CLOCK_MONOTONIC, &end) != 0) {
        return 1;
    }

    double elapsed = (double)(end.tv_sec - start.tv_sec)
                   + (double)(end.tv_nsec - start.tv_nsec) / 1000000000.0;
    printf("clock_gettime elapsed: %.6f seconds (work=%lu)\n", elapsed, total);
    return 0;
}

Subtracting the fields this way works even when the fractional field in the ending reading is smaller, because the seconds difference contributes the corresponding whole seconds. For applications that need a normalized timespec result, borrow one second and add one billion nanoseconds when the fractional difference is negative.

Measure CPU Time with clock

clock from <time.h> reports processor time used by the current process, not elapsed wall time. Its result is a clock_t count of ticks; divide the difference by CLOCKS_PER_SEC to convert it to seconds. The tick scale and useful resolution depend on the implementation, and a very short operation may register no useful change. The return value (clock_t)-1 indicates that the processor time is unavailable.

The example checks both readings and makes the loop result observable. Its 49,995,000 total fits the minimum 32-bit range of unsigned long; the output includes that work count and the calculated CPU duration. The timing value below is illustrative because it varies by system and build.

#include <stdio.h>
#include <time.h>

int main(void) {
    clock_t start = clock();
    if (start == (clock_t)-1) {
        return 1;
    }

    volatile unsigned long total = 0;
    for (unsigned long i = 0; i < 10000UL; ++i) {
        total += i;
    }

    clock_t end = clock();
    if (end == (clock_t)-1) {
        return 1;
    }
    double cpu_seconds = (double)(end - start) / CLOCKS_PER_SEC;
    printf("clock CPU duration: %.6f seconds (work=%lu)\n", cpu_seconds, total);
    return 0;
}

CPU time can be useful when you want to estimate how much processor time a computation consumed. It does not include the full waiting time for sleep, network, disk, or other blocked operations. In a multithreaded process, the reported process CPU time can accumulate across threads, so it can exceed the wall time for the measured interval.

Choose the Right Clock for Your Measurement

Choose the clock according to the quantity you need:

  • For a duration that includes waiting and scheduling, use clock_gettime with CLOCK_MONOTONIC where available.
  • For older Unix-like code that needs a simple wall-clock reading, gettimeofday is an option, with the limitation that wall time can be adjusted.
  • For CPU consumed by the process, use clock and convert ticks with CLOCKS_PER_SEC.

Keep the start and end calls close to the work being measured, and run the measurement more than once when comparing alternatives. System load, compiler optimization, hardware, and the measured operation all affect timings. For very short work, measure a larger batch or repeat the operation and divide by the repetition count; avoid interpreting printed decimal places or a nanosecond field as a guarantee of precision. Check every timing call before using its result, and ensure the measured work has an observable effect. These methods measure different things, so compare results only when the chosen clock matches the question.