gpt4 book ai didi

c - 函数调用的测试条件和执行大致相同的简单测试

转载 作者:太空宇宙 更新时间:2023-11-04 04:57:57 25 4
gpt4 key购买 nike

我正在使用两个版本的函数进行基准测试以过滤链表,一个接收谓词函数作为参数,另一个使用“宏模板”将谓词内置到函数中。我希望第一个运行得更慢,因为它在每次迭代时都进行函数调用,但在我的盒子上它们的速度大致相同。关于为什么会发生这种情况的任何线索?感谢您的帮助。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

struct list_t {
int val;
struct list_t *next;
};
typedef struct list_t list_t;

// Removes elements not matching the predicate.
// NOTE: This is not freeing the removed elements.

list_t *keep(int (*predfun)(int,int), int predarg, list_t *list) {
list_t *this, *prev;

for (this=list, prev=NULL; this; prev=this, this=this->next) {
if (!predfun(this->val, predarg)) {
if (!prev) {
list = this->next;
}
else {
prev->next = this->next;
}
}
}

return list;
}

int less(int a, int b) {
return a<b;
}

// A "template" macro for the keep function.
// The idea is to embed the predicate into the function, so that we
// don't have to make a function call on each iteration.

#define build_keep(test) { \
list_t *this, *prev; \
\
for (this=list, prev=NULL; this; prev=this, this=this->next) { \
if (!(test)) { \
if (!prev) { \
list = this->next; \
} \
else { \
prev->next = this->next; \
} \
} \
} \
return list; \
}


list_t *keep_less(int arg, list_t *list) {
build_keep(this->val < arg);
}

#define LEN 1000000
#define MOD 1024

// Creates a new list.
list_t *buildlist() {
int i;
list_t *list, *last, *t;
list=NULL, last=NULL;
srand(0); // Using always the same seed for the benchmark.
for (i=0; i<LEN; i++) {
if (!last) {
last = malloc(sizeof(list_t));
list = last;
}
else {
last->next = malloc(sizeof(list_t));
last = last->next;
}
last->val = rand() % MOD;
}
last->next = NULL;
return list;
}

int main() {
struct timeval t0, t1;
list_t *list, *t;

// With macro.
list = buildlist();
//for (t=list; t; t=t->next) printf("%d ", t->val); printf("\n");
gettimeofday(&t0, NULL);
keep_less(500, list);
gettimeofday(&t1, NULL);
printf("keep_less: %lf\n", (1000000 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec))/1000000.0);
//for (t=list; t; t=t->next) printf("%d ", t->val); printf("\n");

printf("\n");

// Without macro.
list = buildlist();
//for (t=list; t; t=t->next) printf("%d ", t->val); printf("\n");
gettimeofday(&t0, NULL);
keep(less, 500, list);
gettimeofday(&t1, NULL);
printf("keep: %lf\n", (1000000 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec))/1000000.0);
//for (t=list; t; t=t->next) printf("%d ", t->val); printf("\n");

return 0;
}

这里的输出是:

keep_less: 0.181019

keep: 0.185590

最佳答案

我不会说结果大致相同 - 您确实看到了 4 毫秒 (~2%) 的差异,支持即时版本。

这实际上是相当可观的 - 仅通过保存一个函数调用就可以实现如此高的节省,因为您的测试函数一开始做的很少。如果您希望从此优化中获得更多 yield ,您可能会偶然发现 important lesson ...(就个人而言,我必须每隔几周重新学习一次:])

关于c - 函数调用的测试条件和执行大致相同的简单测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3217482/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com