我正在观看一些视频,其中非常强调未初始化值的速度。然而,我看过另一个视频,指出初始化值实际上更快。我写了以下测试:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
void a(int size) {
int* a = malloc(sizeof(int) * size);
memset(a, 0, sizeof(int) * size);
for(int i = 0; i < size; i++) {
a[i] = i;
}
free(a);
}
void b(int size) {
int* a = malloc(sizeof(int) * size);
for(int i = 0; i < size; i++) {
a[i] = i;
}
free(a);
}
int test(void fun(int), int runs, int size) {
int time = 0;
for(int i = 0; i < runs; i++) {
struct timeval beg = {0}, end = {0};
gettimeofday(&beg, NULL);
fun(size);
gettimeofday(&end, NULL);
int usec_diff = end.tv_usec - beg.tv_usec;
if(usec_diff < 0) {
time += 1000000;
} else {
time += usec_diff;
}
}
return time;
}
int main() {
int a_3 = test(&a, 100000, 1000);
int b_3 = test(&b, 100000, 1000);
printf("b/a ^3: %f\n", (float)b_3 / a_3);
int a_4 = test(&a, 100000, 10000);
int b_4 = test(&b, 100000, 10000);
printf("b/a ^4: %f\n", (float)b_4 / a_4);
int a_5 = test(&a, 100000, 100000);
int b_5 = test(&b, 100000, 100000);
printf("b/a ^5: %f\n", (float)b_5 / a_5);
}
我只是想知道这是否是一个好的测试,以及是否相信结果。我得到以下输出:
eck@eck:~/src/test$ ./main
b/a ^3: 2.764046
b/a ^4: 0.989866
b/a ^5: 0.990233
这似乎很合理,但我想问一下,因为我以前从未写过这样的测试。
编辑:我记得您可以查看生成的程序集,我发现使用 -O1,两个函数都会生成相同的程序集。但是,我不确定您是否可以在更复杂的场景中执行此操作,并且仍然希望澄清初始化与未初始化的事情。
您的测量方法是错误的。
a
和b
将被优化为返回函数: b:
0000000000401dd0: endbr64
0000000000401dd4: ret
a:
0000000000401de0: endbr64
0000000000401de4: ret
即使函数被简化为简单的
ret
语句,你的代码也会显示无意义的结果。
b/a ^3: 1.580129
b/a ^4: 0.376331
b/a ^5: 0.378220
或
b/a ^3: 1.003253
b/a ^4: 1.079337
b/a ^5: 0.243827
所以你无法通过这种方式测量执行时间。
您还需要修改函数,使其不被编译器优化:
int *a(size_t size) {
int* a = malloc(sizeof(int) * size);
memset(a, 0, sizeof(int) * size);
for(size_t i = 0; i < size; i++) {
a[i] = i;
}
return a;
}
int *b(size_t size) {
int* a = malloc(sizeof(int) * size);
for(size_t i = 0; i < size; i++) {
a[i] = i;
}
return a;
}
double test(int *fun(size_t), size_t runs, size_t size) {
clock_t begin = clock();
int *a;
for(size_t i = 0; i < runs; i++) {
a = fun(size);
free(a);
}
clock_t end = clock();
double time = (double)(end - begin) / CLOCKS_PER_SEC;
return time;
}
int main() {
double a_3 = test(&a, 100000ULL, 1000);
double b_3 = test(&b, 100000ULL, 1000);
printf("b/a ^3: %f\n", b_3 / a_3);
double a_4 = test(&a, 100000ULL, 10000);
double b_4 = test(&b, 100000ULL, 10000);
printf("b/a ^4: %f\n", b_4 / a_4);
double a_5 = test(&a, 100000ULL, 100000);
double b_5 = test(&b, 100000ULL, 100000);
printf("b/a ^5: %f\n", b_5 / a_5);
}
结果:
b/a ^3: 0.760627
b/a ^4: 0.772483
b/a ^5: 0.732345
将内存归零会增加显着的开销。