8

I would like to know what lines of C code to add to a program so that it tells me the total time that the program takes to run. I guess there should be counter initialization near the beginning of main and one after the main function ends. Is the right header clock.h?

Thanks a lot...

Update I have a Win Xp machine. Is it just adding clock() at the beginning and another clock() at the end of the program? Then I can estimate the time difference. Yes, you're right it's time.h.

Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <share.h>
#include <time.h>


void f(long double fb[], long double fA, long double fB);

int main() {

clock_t start, end;
start = clock();


const int ARRAY_SIZE = 11;

long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);

int i;
long double A, B;

if (z == NULL) {
    printf("Out of memory\n");
    exit(-1);
}

A = 0.5;
B = 2;


for (i = 0; i < ARRAY_SIZE; i++) {
    z[i] = 0;
}

z[1] = 5;

f(z, A, B);

for (i = 0; i < ARRAY_SIZE; i++)
    printf("z is %.16Le\n", z[i]);



free(z);
z = NULL;

end = clock();
printf("Took %ld ticks\n", end-start);
printf("Took %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);



return 0;  
}  

void f(long double fb[], long double fA, long double fB) {
    fb[0] = fb[1]* fA;
    fb[1] = fb[1] - 1;
    return;
 }  

Some errors with MVS2008:

testim.c(16) : error C2143: syntax error : missing ';' before 'const'  
testim.c(18) :error C2143: syntax error : missing ';' before 'type'  
testim.c(20) :error C2143: syntax error : missing ';' before 'type'   
testim.c(21) :error C2143: syntax error : missing ';' before 'type'    
testim.c(23) :error C2065: 'z' : undeclared identifier   
testim.c(23) :warning C4047: '==' : 'int' differs in levels of indirection from 'void *'  
testim.c(28) : error C2065: 'A' : undeclared identifier
testim.c(28) : warning C4244: '=' : conversion from 'double' to 'int', possible loss of data   

and it goes to 28 errors. Note that I don't have any errors/warnings without your clock codes.

LATEST NEWS: I unfortunately didn't get a good reply here. But after a search on Google, the code is working. Here it is:

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


void f(long double fb[], long double fA);

int main() {

clock_t start = clock();


const int ARRAY_SIZE = 11;

long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);

int i;
long double A;

if (z == NULL) {
printf("Out of memory\n");
exit(-1);
}

A = 0.5;


for (i = 0; i < ARRAY_SIZE; i++) {
z[i] = 0;
}

z[1] = 5;

f(z, A);

for (i = 0; i < ARRAY_SIZE; i++)
printf("z is %.16Le\n", z[i]);



free(z);
z = NULL;

printf("Took %f seconds\n", ((double)clock()-start)/CLOCKS_PER_SEC);



return 0;
}

void f(long double fb[], long double fA) {
fb[0] = fb[1]* fA;
fb[1] = fb[1] - 1;
return;
}

Cheers

Update on April 10: Here's a better solution thanks to "JustJeff"

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void f(long double fb[], long double fA);

const int ARRAY_SIZE = 11;

int main(void)
{

   long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
   int i;
   long double A;

   LARGE_INTEGER freq;
   LARGE_INTEGER t0, tF, tDiff;
   double elapsedTime;
   double resolution;

   if (z == NULL) {
   printf("Out of memory\n");
   exit(-1);
   }
   QueryPerformanceFrequency(&freq);
   QueryPerformanceCounter(&t0);
   // code to be timed goes HERE
   {
    A = 0.5;


    for (i = 0; i < ARRAY_SIZE; i++) {
    z[i] = 0;
    }

    z[1] = 5;
    f(z, A);


    for (i = 0; i < ARRAY_SIZE; i++)
    printf("z is %.16Le\n", z[i]);

    free(z);
    z = NULL;

   }
QueryPerformanceCounter(&tF);
tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
resolution = 1.0 / (double) freq.QuadPart;
printf("Your performance counter ticks %I64u times per second\n", freq.QuadPart);
printf("Resolution is %lf nanoseconds\n", resolution*1e9);
printf("Code under test took %lf sec\n", elapsedTime);
return 0;
}


void f(long double fb[], long double fA) {
fb[0] = fb[1]* fA;
fb[1] = fb[1] - 1;
return;
}

It works both with MVS2008 and with Borland C++ builderX from 2003.

yCalleecharan
  • 4,656
  • 11
  • 56
  • 86
  • 1
    You can post an answer and accept it if you feel you now have the best answer yourself. Doing so can be helpful to someone else searching for an answer to the question at hand (and I'm sure other people search for this all the time). – Cam Apr 07 '10 at 23:22
  • I don't know if I have the right answer. But it's working. I always welcome constructive suggestions as I'm still learning. Can I accept (place a tick) my own answer? – yCalleecharan Apr 08 '10 at 08:25
  • Yes, you can. And by the way, don't mean to be rude, but how didn't you get a good reply here? You got a couple of nice answers which should work. If you get errors, that's your own code, not what the answerers gave you. If you don't think the answers you got are good, please say how so we can improve them. – Javier Apr 08 '10 at 18:32
  • I tested the suggestions here with MVS2008 and I've been getting errors as I mentioned in my post. I'm a novice in C programming. I can't say why the suggested codes here are not working. I got an answer from Google, tested it with my code and it seems to be working. As I improve my knowledge of C with time, I can come back someday and point out any mistakes if any in the suggested codes here. There might be something with my own code. I don't know this yet. I'm here to learn and share knowledge. With my limited knowledge in C, it's hard for me to be the information giver but this will change. – yCalleecharan Apr 09 '10 at 05:10

6 Answers6

6

On Unix (I think) systems, the time command with the name of your program as a command-line argument will tell you the time the program takes to run. Note that this measures the execution time of the whole program. If you need to test just one part, include time.h and use the clock function, more or less like this:

#include <time.h>

int main() {
    clock_t start;
    clock_t end;
    int function_time;
    start = clock();
    function_you_want_to_time();
    end = clock();
    /* Get time in milliseconds */
    function_time = (double)(end - start) / (CLOCKS_PER_SEC / 1000.0);
    return 0;
}

That will give you the time in milliseconds (notice the / 1000.0 part). If you want seconds, remove / 1000.0. If you want plain clock ticks, which will be more accurate, make function_time a clock_t and replace the function_time = ... line with:

function_time = end - start;

To time the whole program, I suggest to make a function called _main() or something, move all your program related code from main() (not the timing code!) to that function, and calling it from main(). That way, it's more clear what's the timing code and what's the rest of the program.

Javier
  • 4,552
  • 7
  • 36
  • 46
  • One downside of this is that if you're only wanting to time the actual computation portion of something, for instance, and want to not include resource/data loading times or output times or whatnot, the `time` command can't do this (since it times the entire execution). – Amber Apr 07 '10 at 09:49
  • That's true. Apparently the `clock()` function is better for that, but I didn't know about it. I'll add a sentence. – Javier Apr 07 '10 at 09:54
  • BTW, if you want to time the whole program, place the `clock()` calls at the beginning and at the end. Also, can someone tell me if it's correct to divide by `CLOCKS_PER_SEC`? – Javier Apr 07 '10 at 10:01
  • Thanks. Does function_you_want_to_time() has to take an argument? I want to time the whole program. – yCalleecharan Apr 07 '10 at 10:05
  • @yCalleecharan: If you want to time the whole program, like I said, replace the `function_you_want_to_time();` line with the rest of the program. It doesn't matter if the function takes an argument. If you want to be really careful about the measuring, move everything in main() to another function and call that from main(). That's so you don't declare variables before you start timing. For C99 or C++, this doesn't apply- – Javier Apr 07 '10 at 23:11
  • @yCalleecharan: I forgot, if you want to be really careful you can take out the `/ CLOCKS_PER_SEC` and make function_time a clock_t, so you get clock count instead of seconds. I'll add that to the answer. – Javier Apr 07 '10 at 23:13
  • Thanks. Is 1 clock tick equal to 1 s? – yCalleecharan Apr 08 '10 at 09:39
  • @yCalleecharan: No. It's a lot less. That's why why divide by `CLOCKS_PER_SEC`. – Javier Apr 08 '10 at 09:42
3

You could use the clock() function (in <time.h>) if you want to test a block of code, or the time program on *nix, as another answerer suggested. E.g.

> time ./foo my args

For clock, you need to subtract the difference between two checkpoints. E.g.

#include <time.h>

void f() {
  clock_t start, end;

  start = clock();

  // some long code.

  end = clock();
  printf("Took %ld ticks\n", end-start);
  // or in (fractional) seconds.
  printf("Took %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);
}

Update

Regarding your new errors, you can't mix code and declarations in VC. You mustn't call any functions then continue to declare variables. Declare all your vars at the top, or compile with C++ mode.

Alex Budovski
  • 17,947
  • 6
  • 53
  • 58
  • I get lots of errors. Do we have to define the type of clock_t, start? – yCalleecharan Apr 07 '10 at 10:03
  • Do we need to have the void f() ? Or can we just put clock_t start, end; start = clock();...end = clock();printf("Took %ld ticks\n", end-start); inside main? – yCalleecharan Apr 07 '10 at 10:29
  • Sorry, this is not working for me. MVS208 complains stupidly with 102 errors. The compiler complains that lots of things are undefined. Are you sure you're not missing anything in your code snippet? – yCalleecharan Apr 07 '10 at 11:01
  • Post your code and errors. (I presume you included for printf?) – Alex Budovski Apr 07 '10 at 11:23
  • I really don't understand how my program is wrong. I'm using C. The program works fine without any warnings when I don't have your clock codes. Show me what to modify in my code and have it still as a C program. Thanks. – yCalleecharan Apr 07 '10 at 12:34
3

If you need a total for your program then in Linux console:

$ time myProgram

You can also use time.h in your code.

#include <time.h>

int main(){
  time_t start, end;
  start = time(0);

  /* some working code */

  end = time(0);
  printf("%i seconds", end - start );
}
Draco Ater
  • 20,820
  • 8
  • 62
  • 86
1

You probably want time.h, and the clock() function.

Amber
  • 507,862
  • 82
  • 626
  • 550
1

If you're on windows and you want to measure stuff down in the microseconds, investigate QueryPerformanceCounter() and QueryPerformanceFrequency(). On many systems these can resolve full processor clock periods, third of a nanosecond stuff, and I don't believe I've ever seen it any more coarse than 3.5795MHz, still well under a microsecond.

You call QueryPerformanceFrequency() to determine how many counts per second the counter counts. Then call QueryPerformanceCounter() before your code under test, and then again after. Delta the two readings of QPC and divide by the period from QPF and you get the elapsed time between the two QPC calls. Like so ...

LARGE_INTEGER freq;
LARGE_INTEGER t0, tF, tDiff;
double elapsedTime;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&t0);
// code to be timed goes HERE
QueryPerformanceCounter(&tF);
tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
// elapsedTime now has your measurement, w/resolution given by freq

Evidently these access a hardware counting device that is tied to some system oscillator on the main board, in which case they shouldn't suffer jitter from software load. The resolution you get depends on your system.

FOLLOW UP

Here's a very simple complete program that demonstrates the interface:

#include <windows.h>
int main(void)
{
    LARGE_INTEGER freq;
    LARGE_INTEGER t0, tF, tDiff;
    double elapsedTime;
    double resolution;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&t0);
    // code to be timed goes HERE
    {
        Sleep(10);
    }
    QueryPerformanceCounter(&tF);
    tDiff.QuadPart = tF.QuadPart - t0.QuadPart;
    elapsedTime = tDiff.QuadPart / (double) freq.QuadPart;
    resolution = 1.0 / (double) freq.QuadPart;
    printf("Your performance counter ticks %I64u times per second\n", freq.QuadPart);
    printf("Resolution is %lf nanoseconds\n", resolution*1e9);
    printf("Code under test took %lf sec\n", elapsedTime);
    return 0;
}

For something as simple as this, it's quicker to skip the IDE, just save it in a foo.c file and (assuming MS VS 2008) use the command line

cl foo.c

to build it. Here's the output on my system:

Your performance counter ticks 3579545 times per second
Resolution is 279.365115 nanoseconds
Code under test took 0.012519 sec
JustJeff
  • 12,640
  • 5
  • 49
  • 63
  • Thanks. This seems a bit too advanced for me :). – yCalleecharan Apr 08 '10 at 16:31
  • the calls are really quite simple, the way you use them is the same as with clock(), the resolution is far better than with clock(), and the worst part is working with 64 bit integers. Well, it's also windows specific, but you did tag windows. – JustJeff Apr 09 '10 at 00:08
  • Thanks. I've added the header windows.h but I still get errors. An error arises at line QueryPerformanceFrequency(&freq); The compiler complains: E2293 ) expected at line 12. Another is: QueryPerformanceCounter(&t0); error is: E2293 ) expected at line 13. Another is tDiff = tF - t0; error is: E2096 Illegal structure operation in function main at line 57. Last error: elapsedTime = tDiff / (double) freq; error is: E2110 Incompatible type conversion in function main at line 58. I compiled this using Borland C++ BuilderX. Any suggestion? – yCalleecharan Apr 09 '10 at 05:38
  • grab microsoft visual studio express 2005 or 2008, they're free, and ideal for windows work. – JustJeff Apr 09 '10 at 09:58
  • Not sure how old the Borland compiler you're using is, there may be a way you could finesse it into working, but it certainly does work with MS VS Express 2008, and I believe the 2005 edition of same. – JustJeff Apr 09 '10 at 10:51
  • Ok thanks. I'm using the borland c++ BuilderX which came out in 2003. Yes I have MS VS 2008. What I don't like with VS is that it creates about 15 files for a project while builderX creates only 7. Of course I don't know what the other files are used for :) but I believe they're helpful in the debugging process. – yCalleecharan Apr 09 '10 at 12:55
  • I get several errors with MVS2008. Errors like: error C2143: syntax error : missing ')' before '&' due to the line QueryPerformanceFrequency(&freq);, error: syntax error : missing '{' before '&' due to the same line, error syntax error : '&' due to same line. All errors repeat for subsequent line: QueryPerformanceCounter(&t0); Any suggestions? – yCalleecharan Apr 09 '10 at 21:12
  • Thanks a lot for your kind efforts. Please see my updated post. It works fine with MVS and with Borland. Can you please explain to me the phrases: "Your performance counter ticks 3579545 times per second" and "Resolution is 279.365115 nanoseconds". Resolution I guess is just the precision, but what about performance counter? – yCalleecharan Apr 10 '10 at 08:50
  • The counter is a hardware register (64 bits), probably in the northbridge chip, but could be in the CPU for all I know. It freely counts up at a rate that depends on your system's hardware design, independently from CPU activity. Inside the QPC call, the CPU just reads that counter. You have to read the frequency (via QPF) to know how long each count takes. Common values are full processor speed (~2.4 to 3GHz!) and 3.579MHz, which is related to legacy video signal generation. – JustJeff Apr 10 '10 at 18:33
  • Ok. Thanks for the info and for giving me a code that works. By the way, MVS2008 is much faster than Borland C++ builderX from 2003 around the order of magnitude of 2. – yCalleecharan Apr 10 '10 at 21:06
0

You can try GetTickCount also. Clock will also work fine. But, I guess clock values will change if some other process or some one manually changes the system time, wheareas GetTickCount values are not affected by that.

Jay
  • 24,173
  • 25
  • 93
  • 141