2

I want to create a function that measures execution time of any function that is passed as it's argument no matter how many arguments the function that is passed has.

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

typedef void (*FUNC_PTR)(int, int);

void print_range(int n1, int n2)
{
    int i;
    for(i=n1; i<n2; i++){
            printf("%d\n", i);
    }   
}

void measureTime(FUNC_PTR ptr, int n1, int n2)
{
    time_t start_time = clock();
    ptr(n1, n2); 
    time_t end_time = clock();
    printf("%f\n", (double)end_time - start_time);

}

main()
{   
    int n1 = 1, n2 = 1000;
    FUNC_PTR ptr = print_range;
    measureTime(ptr, n1, n2);
}

I got it working for this specific case of passing print_range that has 2 arguments.

Is there any way to make measureTime function execute any function that is passed as FUNC_PTR ptr without having to pass print_range n1 and n2 arguments to measureTime function.

So for instance function that is passed as ptr can have any number of arguments and measureTime will still work.

void measureTime(FUNC_PTR ptr)
{
    time_t start_time = clock();
    ptr;
    time_t end_time = clock();
    printf("%f\n", (double)end_time - start_time);
}

And if above can work how would than main look like?

  • 1
    There's no way to pass "any function", the compiler needs to know in great detail how to generate the function call. There are [variadic functions](http://en.wikipedia.org/wiki/Variadic_function) that take a variable number of parameters, but I assume that's not what you're talking about. – Mark Ransom May 20 '15 at 21:24
  • You might check out [closures/blocks in C](http://stackoverflow.com/questions/4393716/is-there-a-a-way-to-achieve-closures-in-c) – timato May 20 '15 at 21:56
  • @John consider accepting one of the answer. – Xaqq May 22 '15 at 08:40

4 Answers4

1

First of all be carefull as clock() returns clock cycles and not seconds, to get the seconds you must divide the result from Clock() with CLOCKS_PER_SEC wich is defined in time.h I guess it's seconds what you want. if not then just ignore that.

you could create a struct with the values you wish for your problem

something like this

typedef struct values {
   int *v
} *VALUES;

where you would store your values. You can store as many as you wish as long as you write a = malloc (N*(sizeof (int))) with N being how many ints you want to store! Like this you can have 1000000000000 variables, just one, or maybe even zero, it's your choice, these are variables that wont be lost untill the end of the program. You just need to have ptr receiving a variable of type VALUES.

to access the values you just do VALUES a; a->v; and there you go, simple as that!

Hope I helped.

1

Doing so with function pointer is not possible in C.

Hopefully, I believe there is a viable alternative, provided you can use it. It uses macro to wrap the function call instead of an intermediary function.

Here is a possible implementation:

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

#define CHECK_TIME(fct, args...) CHECK_TIME_IMPL(fct, __COUNTER__ , args)

#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )

#define CHECK_TIME_IMPL(fct, COUNTER, args...) time_t MACRO_CONCAT(start_time, COUNTER) = clock(); \
  (fct)(args); \
  time_t MACRO_CONCAT(end_time, COUNTER) = clock();     \
  printf("%f\n", (double)MACRO_CONCAT(end_time, COUNTER) - MACRO_CONCAT(start_time, COUNTER));

void print_range(int n1, int n2)
{
  int i;
  for(i=n1; i<n2; i++){
    printf("%d\n", i);
  }
}

void something_else(char c) {
  printf("Char: %c\n", c);
}

void no_param() {printf("Doing nothing\n");}

int main()
{
  int n1 = 1, n2 = 10;

  CHECK_TIME(print_range, n1, n2);
  CHECK_TIME(print_range, n1, n2);
  CHECK_TIME(something_else, 'c');
  CHECK_TIME(no_param);

  return 0;
}

Note that I did not fix the problem related to the misuse of clock().

Xaqq
  • 4,308
  • 2
  • 25
  • 38
  • OK. I added CLOCKS_PER_SEC devide in printf on line 12 and it prints time for each function. It works. Thanks. I just don't get what's happening with all these defines. May I ask what literature to look at to find out more if you don't have time to explain it in more detail. And thanks again :) – John Rodens May 23 '15 at 18:16
  • 1
    @JohnRodens Glad it works for you :). All these defines are preprocessor (ab)use to make it works. As you can see, you use 2 temporary variable when checking the time for 1 function. Meaning you have to generate multiple variable name to make it works. This is what `__COUNTER__` does. The `MACRO_CONCAT` helps build a unique variable name for temporary variable. `args...` is as variadic macro argument to let us define a macro with any number of parameter. So I recommend you read about: 1) Variadic macros 2) macro string concatenation to better understand how it works. – Xaqq May 24 '15 at 18:12
0

You need a language that supports lambda expression. As far as I know, C does not support lambda expression so far. The following is a C++0x snippet that shows how this can be done:

#include <iostream>

using namespace std;

template<typename F>
 void timeIt(const F& f) {
    cout << "start..." << endl;
    f();
    cout << "end..." << endl;
}

int f(int n) {
    return n <= 1 ? 1 : n*f(n-1);
}

void main() {
    int n = 20;
    timeIt([n] {
        cout << "result=" << f(n) << endl;
    });
}
Codism
  • 5,928
  • 6
  • 28
  • 29
-1

After doing some more research I have found out that I was trying to do a callback in c. Didn't realize it isn't possible the way I wanted it.