Функция, которая измеряет время выполнения любой функции, переданной в качестве параметра

Я хочу создать функцию, которая измеряет время выполнения любой функции, которая передается в качестве аргумента, независимо от того, сколько аргументов передана функция.

#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);
}

Я получил это работает для этого конкретного случая прохождения print_range у этого есть 2 аргумента.

Есть ли способ сделать measureTime Функция выполняет любую функцию, которая передается как FUNC_PTR ptr без необходимости проходить print_rangen1 а также n2 аргументы measureTime функция.

Так, например, функция, которая передается как ptr может иметь любое количество аргументов и measureTime все еще будет работать.

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

И если выше, может работать, как будет выглядеть, чем основной?

4 ответа

Решение

Это невозможно с указателем на функцию в C.

Надеюсь, я считаю, что есть жизнеспособная альтернатива, при условии, что вы можете ее использовать. Он использует макрос для переноса вызова функции вместо промежуточной функции.

Вот возможная реализация:

#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;
}

Обратите внимание, что я не исправил проблему, связанную с неправильным использованием clock(),

Прежде всего, будьте осторожны, так как clock() возвращает такты, а не секунды, чтобы получить секунды, вы должны разделить результат от Clock() на CLOCKS_PER_SEC, который определен во времени. Я думаю, это секунды, которые вы хотите. если нет, то просто игнорируйте это.

Вы можете создать структуру со значениями, которые вы хотите для вашей проблемы

что-то вроде этого

typedef struct values {
   int *v
} *VALUES;

где вы будете хранить свои ценности. Вы можете хранить столько, сколько пожелаете, до тех пор, пока вы пишете = malloc (N*(sizeof (int))), где N - это сколько целых чисел вы хотите сохранить! Таким образом, вы можете иметь 1000000000000 переменных, всего одну или, может быть, даже ноль, это ваш выбор, это переменные, которые не будут потеряны до конца программы. Вам просто нужно, чтобы ptr получал переменную типа VALUES.

чтобы получить доступ к значениям, которые вы просто делаете ЗНАЧЕНИЯ a; a->v; и все, просто!

Надеюсь, я помог.

Вам нужен язык, который поддерживает лямбда-выражения. Насколько я знаю, C пока не поддерживает лямбда-выражения. Ниже приведен фрагмент кода C++0x, который показывает, как это можно сделать:

#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;
    });
}

Проведя дополнительное исследование, я обнаружил, что пытался сделать обратный вызов в c. Не понимал, что это невозможно так, как я этого хотел.

Другие вопросы по тегам