【问题标题】:Function that meassures execution time of any function passed as parameter测量作为参数传递的任何函数的执行时间的函数
【发布时间】:2015-05-20 21:22:01
【问题描述】:

我想创建一个函数来测量作为参数传递的任何函数的执行时间,无论传递的函数有多少参数。

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

我让它适用于传递具有 2 个参数的 print_range 的特定情况。

有没有办法让measureTime 函数执行任何作为FUNC_PTR ptr 传递的函数,而不必将print_range n1n2 参数传递给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);
}

如果上面可以工作,那么 main 会是什么样子?

【问题讨论】:

  • 没有办法传递“任何函数”,编译器需要非常详细地知道如何生成函数调用。有variadic functions 采用可变数量的参数,但我认为这不是你在说的。
  • 您可以查看closures/blocks in C
  • @John 考虑接受其中一个答案。

标签: c function-pointers


【解决方案1】:

在 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()相关的问题。

【讨论】:

  • 好的。我在第 12 行的 printf 中添加了 CLOCKS_PER_SEC ,它打印了每个函数的时间。有用。谢谢。我只是不明白所有这些定义发生了什么。如果您没有时间更详细地解释它,请问可以查看哪些文献以了解更多信息。再次感谢:)
  • @JohnRodens 很高兴它对你有用:)。所有这些定义都是预处理器(ab)用于使其工作。如您所见,您在检查 1 个函数的时间时使用了 2 个临时变量。这意味着您必须生成多个变量名称才能使其正常工作。这就是__COUNTER__ 所做的。 MACRO_CONCAT 有助于为临时变量建立一个唯一的变量名。 args... 是可变参数宏参数,让我们定义一个带有任意数量参数的宏。因此,我建议您阅读以下内容:1)可变参数宏 2)宏字符串连接以更好地了解它的工作原理。
【解决方案2】:

首先要小心,因为 clock() 返回时钟周期而不是秒,要获得秒数,您必须将 Clock() 的结果与 time.h 中定义的 CLOCKS_PER_SEC 相除 我想这是你想要的几秒钟。如果不是,那就忽略它。

您可以使用您希望解决问题的值创建一个结构

类似的东西

typedef struct values {
   int *v
} *VALUES;

您将存储您的值的位置。只要您编写 a = malloc (N*(sizeof (int))) ,您就可以存储任意数量的整数,其中 N 是您要存储的整数数量!像这样,您可以拥有 1000000000000 个变量,只有一个,甚至可能为零,这是您的选择,这些变量在程序结束之前不会丢失。你只需要让 ptr 接收一个 VALUES 类型的变量。

访问您刚刚执行的值 价值观a->v; 就这么简单!

希望我能帮上忙。

【讨论】:

    【解决方案3】:

    您需要一种支持 lambda 表达式的语言。据我所知,到目前为止,C 还不支持 lambda 表达式。下面是一个 C++0x sn-p,它展示了如何做到这一点:

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

    【讨论】:

      【解决方案4】:

      在做了更多研究之后,我发现我正在尝试在 c 中进行回调。没想到这不可能如我所愿。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        • 2017-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多