41

I have this program which prints the time difference between 2 different instances, but it prints in accuracy of seconds. I want to print it in milliseconds and another in nanoseconds difference.

//Prints in accuracy of seconds

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

int main(void)
{
    time_t now, later;
    double seconds;

    time(&now);
    sleep(2);

    time(&later);
    seconds = difftime(later, now);

    printf("%.f seconds difference", seconds);
}

How can I accomplish that?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
RajSanpui
  • 11,556
  • 32
  • 79
  • 146
  • 1
    What platform are you on? – interjay Apr 29 '13 at 09:40
  • 2
    this might help: http://stackoverflow.com/questions/13610471/calculating-function-time-in-nanoseconds-in-c-code – İsmet Alkan Apr 29 '13 at 09:40
  • @interjay: Sorry i should have mentioned that, it's Linux. gcc compiler. – RajSanpui Apr 29 '13 at 09:42
  • 1
    You can't have nanoseconds precision. http://stackoverflow.com/questions/13610471/calculating-function-time-in-nanoseconds-in-c-code – lucasg Apr 29 '13 at 09:42
  • @georgesl you _can_ get time to nanosecond precision on Linux. This is not guaranteed to be nanosecond accurate though as I believe that it may be an interpolation between two microsecond values based on the CPU's internal clock on most architectures. You can always use `clock_getres` to find it though. – Will Apr 29 '13 at 10:30
  • @Will : even if you have nanoseconds resolution with CPU's internal clock, FSB's speed is only a fraction of that (typically 100-500 Mhz) so you have to pray for your loop to stay within L1 cache. – lucasg Apr 29 '13 at 11:10
  • @georgesl indeed. The value returned may be very precise but wildly inaccurate. – Will Apr 29 '13 at 11:16

3 Answers3

64

Read first the time(7) man page.

Then, you can use clock_gettime(2) syscall (you may need to link -lrt to get it).

So you could try

    struct timespec tstart={0,0}, tend={0,0};
    clock_gettime(CLOCK_MONOTONIC, &tstart);
    some_long_computation();
    clock_gettime(CLOCK_MONOTONIC, &tend);
    printf("some_long_computation took about %.5f seconds\n",
           ((double)tend.tv_sec + 1.0e-9*tend.tv_nsec) - 
           ((double)tstart.tv_sec + 1.0e-9*tstart.tv_nsec));

Don't expect the hardware timers to have a nanosecond accuracy, even if they give a nanosecond resolution. And don't try to measure time durations less than several milliseconds: the hardware is not faithful enough. You may also want to use clock_getres to query the resolution of some clock.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • thats true its work for me. thank you very much @Basile – EsmaeelE Aug 06 '17 at 00:20
  • The hardware not being "faithful enough" to measure sub-ms intervals is a doubtful assertion. If true, it would require an explanation given the accuracy of crystal oscillators. – gsimard Oct 21 '18 at 01:45
  • I am not sure that the typical clock on a typical consumer PC has a relative precision of 1e-10. Most clocks are not that precise. Those that do cost probably more than a car. I cannot even name the provider of such high-precision clocks. – Basile Starynkevitch Oct 21 '18 at 05:52
  • 1
    For computational benchmarking it is better to use CLOCK_PROCESS_CPUTIME_ID instead of CLOCK_MONOTONIC – Lothar Mar 03 '21 at 08:45
  • 1
    I would reorder the computation to minimize rounding errors: `(double) (tend.tv_sec - tstart.tv_sec) + 1.0e-9 * (double) (tend.tv_nsec - tstart.tv_nsec)` – HAL9000 Oct 05 '21 at 21:42
20

timespec_get from C11

This function returns up to nanoseconds, rounded to the resolution of the implementation.

Example from: http://en.cppreference.com/w/c/chrono/timespec_get :

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

int main(void)
{
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    char buff[100];
    strftime(buff, sizeof buff, "%D %T", gmtime(&ts.tv_sec));
    printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec);
}

Output:

Current time: 02/18/15 14:34:03.048508855 UTC

More details here: https://stackoverflow.com/a/36095407/895245

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • This is great. Is there an easy way to concatenate buff and ts.tv_sec into a single string? I attempted to use .append() in cpp with no success. – p.luck Dec 16 '20 at 18:48
  • @p.luck not sure I understand the question. Do you mean concatenate `ts.tv_sec` and `ts.nsec` in a single string? For that something along `strftime %D %T %s` + a second `snprintf` call: https://stackoverflow.com/questions/3774417/sprintf-with-automatic-memory-allocation – Ciro Santilli OurBigBook.com Dec 16 '20 at 21:45
1

here is a simple macro to deal with it

#include <time.h>
#define CHECK_TIME(x) {\
    struct timespec start,end;\
    clock_gettime(CLOCK_REALTIME, &start);\
    x;\
    clock_gettime(CLOCK_REALTIME, &end);\
    double f = ((double)end.tv_sec*1e9 + end.tv_nsec) - ((double)start.tv_sec*1e9 + start.tv_nsec); \
    printf("time %f ms\n",f/1000000); \
    }

and here is how to use it:

CHECK_TIME(foo(a,b,c))
yairgd
  • 39
  • 5