-1

I have a function which can generate 10000 random numbers and write them in a file.

void generator(char filename[])              
{
    int i;
    int n;
    FILE* fp;
    if((fp=fopen(filename,"w+"))==NULL)
    {
        printf("Fail creating file!");
    }
    srand((unsigned)time(NULL));
    for(i=0;i<10000;i++)
    {
        n=rand()%10000;
        fprintf(fp,"%d ",n);
    }
    fclose(fp);
}

How can I get the execution time of this function using C/C++ ?

7 Answers7

6

Code profiling is not a particularly easy task (or, as we oft-say in programming, it's "non-trivial".) The issue is because "execution time" measured in seconds isn't particularly accurate or useful.

What you're wanting to do is to measure the number of CPU cycles. This can be done using an external tool such as callgrind (one of Valgrind's tools). There's a 99% chance that's all you want.

If you REALLY want to do that yourself in code, you're undertaking a rather difficult task. I know first hand - I wrote a comparative benchmarking library in C++ for on-the-fly performance testing.

If you really want to go down that road, you can research benchmarking on Intel processors (that mostly carries over to AMD), or whatever processor you've using. However, as I said, that topic is large and in-depth, and far beyond the scope of a StackOverflow answer.

CodeMouse92
  • 6,840
  • 14
  • 73
  • 130
  • 1
    Add to that the fact that the processor could be running at its turbo boost frequency, when it is an Intel chip, and this makes the number of cycles useless as well for timing because its clock frequency is unknown. This is a system specific thing and is not something that can be used from machine to machine. You can use benchmark programs to compare the performance of machines but that is about all you can do. – Careful Now Apr 11 '16 at 18:47
  • Even though you have not solved my problem, I prefer your answer. –  Apr 11 '16 at 18:54
  • @CarefulNow, my benchmarking library does pretty well for comparing the performance of two "tests" (written carefully for proper comparison, of course) on the same machine. It works across all Intel/AMD Linux systems thus far, so long as the code is g++ compiled. I don't bother with other compilers or architectures in that library. It doesn't give perfect results, but it still has pretty tight and consistent ballpark estimates that aren't far off of what Callgrind tells you. – CodeMouse92 Apr 11 '16 at 19:06
  • @Français, I'm glad it was helpful. If this is the answer you're going with, please click the checkmark next to it to "accept" the answer. Otherwise, if you go with someone else's answer, please mark theirs as "accepted". You should accept whichever answer best guides you in the direction you want to go. – CodeMouse92 Apr 11 '16 at 19:29
2

You can use the chrono library;

#include <chrono>

//*****//

auto start = std::chrono::steady_clock::now();
generator("file.txt")
auto end = std::chrono::steady_clock::now();

std::cout << "genarator() took "
              << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << "us.\n";
Daniel
  • 346
  • 3
  • 6
1

You have already some nice C answers that also work with C++.
Here a native C++ solution using <chrono>:

auto tbegin = std::chrono::high_resolution_clock::now(); 
...
auto tend = std::chrono::high_resolution_clock::now();
auto tduration = std::chrono::duration_cast<std::chrono::microseconds>(tend - tbegin).count();

The advantage is that you can switch from microsecond to millisecond, seconds or any other time measurement units very easily.

Note that you may have OS limits to the clocking accuracy (typically 15 milliseconds on windows environment), so that this may give meaningful results only if you're really above this limit.

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138
0
void generator(char filename)
{
    clock_t tStart = clock();
    /* your code here */
    printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}

upd. And add #include <ctime>
0
#include <ctime>
 .....
clock_t start = clock();
...//the code you want to get the execution time for
double elapsed_time = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;
std::cout << elapsed_time << std::endl;//elapsed_time now contains the execution time(in seconds) of the code in between

will give you an approximate(not accurate) execution time of the code between the first and second clock() calls

Biruk Abebe
  • 2,235
  • 1
  • 13
  • 24
0

Try this

    #include <sys/time.h> 

    struct timeval tpstart,tpend; 

    double timeuse; 

    //get time before generator starts
    gettimeofday(&tpstart,NULL); 

    //call generator function
    generator(filename);

    //get time after generator ends
    gettimeofday(&tpend,NULL); 

    //calculate the used time
    timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec; 
    timeuse/=1000000; 

    printf("Used Time:%fsec\n",timeuse);
  • Interesting, but [gettimeofday()]http://man7.org/linux/man-pages/man2/gettimeofday.2.html) is OS dependent (i.e. POSIX and not standard C/C++). It also might suffer from discontinuities in the time settings of the OS – Christophe Apr 11 '16 at 18:58
  • I agree with you. But I do not know a way to keep away from the discontinuities. –  Apr 11 '16 at 19:16
-2

Temporarily make the limit 10000000

Time it with a stopwatch. Divide the time by 1000

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • this assumes that the runtime of the function linearly depends on this limit which is obviously not the case for opening and closing the file – 463035818_is_not_an_ai Apr 11 '16 at 18:47
  • This doesn't account for the program being paged out or interrupted. Also, stop watches are not very accurate (the human pressing the start and stop buttons is not accurate nor consistent). – Thomas Matthews Apr 11 '16 at 20:14