# C++ clock() function acting strangely on my Mac

Discussion in 'Mac Programming' started by JakeD409, Sep 24, 2007.

1. ### JakeD409 macrumors newbie

Joined:
Sep 24, 2007
#1
I'm on a Mac Pro (OS 10.4.10), and I'm trying to complete a programming assignment for my algorithms class. In it, we have to benchmark our sorting algorithm (counting sort, to be specific).

I have the sorting working perfectly. However, I'm trying to use the clock() function to benchmark, and I'm getting some strange results. For test cases 1 and 3 (1 is an already sorted vector of 10,000 ints, from 0 to 9999, and 3 is a vector of 10,000 random ints, ranging from 0 to 9999), I get 0.0000... seconds (even when I have the precision at 20 places). For test case 2 (the reverse of test case 1 - a 10,000-int vector going from 9999 to 0), I always get EXACTLY 0.01000000000000000021 seconds (no matter what else I'm doing or how many times I'm running it).

Originally, I thought "maybe my computer is just that fast and consistant". However, even if I put a large amount of extra time in there (by adding a space to put user input between two clock()s), it comes back with the same results. Also, if I just try to print out the result of a random clock(), I get 0.

This leads me to believe that either I am doing something wrong, or there's something about Mac programming that I don't know. Does anyone have any experience with this?

If it helps, here is the benchmarking portion of my code:

Code:
```// Prepare to benchmark
clock_t start1;
clock_t end1;
double  time1;
clock_t start2;
clock_t end2;
double  time2;
clock_t start3;
clock_t end3;
double  time3;

start1 = clock();
countingSort(input1, output1, ARR_UPPER_BOUND);  // Sort input1
end1   = clock();
time1  = ((double)end1 - (double)start1) / CLOCKS_PER_SEC;

start2 = clock();
countingSort(input2, output2, ARR_UPPER_BOUND);  // Sort input2
end2   = clock();
time2  = ((double)end2 - (double)start2) / CLOCKS_PER_SEC;

start3 = clock();
countingSort(input3, output3, ARR_UPPER_BOUND);  // Sort input3
end3   = clock();
time3  = ((double)end3 - (double)start3) / CLOCKS_PER_SEC;

// Show benchmarks
printf("Time to run test case 1: %.20lf \n", time1);
printf("Time to run test case 2: %.20lf \n", time2);
printf("Time to run test case 3: %.20lf \n", time3);
```
Results:

Code:
```Time to run test case 1: 0.00000000000000000000
Time to run test case 2: 0.01000000000000000021
Time to run test case 3: 0.00000000000000000000 ```

2. ### toddburch macrumors 6502a

Joined:
Dec 4, 2006
Location:
Katy, Texas
#2
Check the return time on your clock() call. The reference says if data is not available, it returns -1. And, (-1)-(-1) = 0.

This is an example I worked out a while back that works. Maybe you can glean something out of it. (It's probably a little "heavy" towards C)

Code:
```#include <iostream>
#include <ctime>

using namespace std ;

int main (int argc, char *const argv[]) {

char nothing[20] ;
char hours[3], minutes[3], seconds[3] ;

struct tm base, *the_time ;

time_t  stime, etime ;

time(&stime) ;  // Get start time in seconds since epoch
the_time = localtime(&stime) ;
base.tm_hour = the_time->tm_hour ;
base.tm_min  = the_time->tm_min ;
base.tm_sec  = the_time->tm_sec ;
cout << "\n2007 Todd Burch." << endl ;
cout << "Program=" << __FILE__ << ", Compile Time = " << __TIME__ << " " << __DATE__ << " / " << endl ;

cout << "Start time was " << base.tm_hour << ":" <<
base.tm_min  << ":" <<
base.tm_sec  << endl;

cout << "Wait for a few seconds, then enter any character..." << endl ;
// Waiting... waiting...
cin >> nothing ;

time(&etime) ; // Get end time in seconds since epoch
the_time = localtime(&etime) ;

sprintf(hours,   "%02d", base.tm_hour ) ;
sprintf(minutes, "%02d", base.tm_min  ) ;
sprintf(seconds, "%02d", base.tm_sec  ) ;

cout << "Start time was " << hours << ":" << minutes << ":" << seconds << endl;

sprintf(hours,   "%02d", the_time->tm_hour ) ;
sprintf(minutes, "%02d", the_time->tm_min  ) ;
sprintf(seconds, "%02d", the_time->tm_sec  ) ;

cout << "End time was   " << hours << ":" << minutes << ":" << seconds << endl;

return 0;
}
```
Todd

3. ### fimac macrumors member

Joined:
Jan 18, 2006
Location:
Finland
#3
gettimeofday

JakeD409, clock() may not have sufficient granularity to accurately measure your test-case. Run your tests 100 or 1000 times -- and remember to divide the elapsed time accordingly

Note: You cannot test clock() with sleep() since sleep does not use processor time!

Alternatively, gettimeofday might work for you (I am not on my Mac right now, so I cannot check it).

4. ### JakeD409 thread starter macrumors newbie

Joined:
Sep 24, 2007
#4
I'm not sure how correct the answers were with regards to clock(), but gettimeofday() worked like a charm. I'm now using this code:

Code:
```timeval start1, start2, start3, end1, end2, end3;
double tmp1, tmp2;

gettimeofday(&start1, NULL);
countingSort(input1, output1, ARR_UPPER_BOUND);  // Sort input1
gettimeofday(&end1, NULL);
tmp1 = start1.tv_sec + (start1.tv_usec / 1000000.0);
tmp2 = end1.tv_sec   + (end1.tv_usec   / 1000000.0);
double time1 = tmp2 - tmp1;

gettimeofday(&start2, NULL);
countingSort(input2, output2, ARR_UPPER_BOUND);  // Sort input2
gettimeofday(&end2, NULL);
tmp1 = start2.tv_sec + (start2.tv_usec / 1000000.0);
tmp2 = end2.tv_sec   + (end2.tv_usec   / 1000000.0);
double time2 = tmp2 - tmp1;

gettimeofday(&start3, NULL);
countingSort(input3, output3, ARR_UPPER_BOUND);  // Sort input3
gettimeofday(&end3, NULL);
tmp1 = start3.tv_sec + (start3.tv_usec / 1000000.0);
tmp2 = end3.tv_sec   + (end3.tv_usec   / 1000000.0);
double time3 = tmp2 - tmp1;

// Show benchmarks
cout.setf(ios::fixed, ios::floatfield);
cout.precision(6);
cout << "Seconds to run test case 1: " << time1 << endl;
cout << "Seconds to run test case 2: " << time2 << endl;
cout << "Seconds to run test case 3: " << time3 << endl;```
and gettings results around here (give or take 0.00005 of a second):
Code:
```Seconds to run test case 1: 0.004105
Seconds to run test case 2: 0.004087
Seconds to run test case 3: 0.004138```
Thanks for the help I appreciate it a lot.