0

假设我在循环中使用数组的一项,例如

INS *in;
for (int i = 0; i < LEN; i++) {
    in = g_ins[i];
    if (strcmp(in->mne, str) == 0)
        return in;
}

如果我使用索引引用每个引用,编译器会针对上面的内容进行优化,或者它真的一次又一次地访问每个索引?

for (int i = 0; i < LEN; i++) {
    if (strcmp(g_ins[i]->mne, str) == 0)
        return g_ins[i];
}
4

4 回答 4

1

很大程度上取决于您的编译器和编译器设置。

不过,一般我不会担心它。

于 2012-08-15T13:52:18.973 回答
1

如果有疑问,您可以尝试一下。例如,将您的两段代码放入函数中:

INS * f1 (INS *g_ins, const char * str)
{
    for (int i = 0; i < LEN; i++) {
        INS *in = &g_ins[i];
        if (strcmp(in->mne, str) == 0)
            return in;
    }
    return NULL;
}

INS * f2 (INS *g_ins, const char * str)
{
    for (int i = 0; i < LEN; i++) {
        if (strcmp(g_ins[i].mne, str) == 0)
            return &g_ins[i];
    }
    return NULL;
}

然后用 -O2 和 -S 编译它们(例如。gcc -std=c99 -O2 -S -Wall code.c -o code.s)。-O2 设置优化级别,-S 告诉编译器生成汇编代码并停止。

然后看汇编代码。

即使您不太了解汇编程序,您也应该能够了解这两个函数的相对大小。对于您的函数,它们编译为相同的代码。

于 2012-08-15T14:30:07.220 回答
0

对于几乎任何级别的优化,编译器可能会为两个片段生成相同的代码。事实上,如果没有优化,没有显式局部变量的版本可能会更好,因为它不需要g_ins[i]显式存储 的值;它可能只是放入一个寄存器并使用两次。

但是,它确实取决于您使用的编译器和优化设置。而且这里的任何区别都不太可能是快速程序和慢速程序之间的区别。

于 2012-08-15T14:09:45.787 回答
0

大多数情况下,编译器会在正常设置中避免此类事情。您的变量是在循环之外声明的,编译器不确定在循环之后是否有进一步使用 INS *in。所以跳过这个阶段不会做太多优化,除了保存几个指令,但可能导致后期输出损坏。

于 2012-08-15T14:10:54.670 回答