按索引访问数组的项目

时间:2012-08-15 13:51:02

标签: c optimization compiler-construction

假设我在循环中使用了一个数组项,比如

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 个答案:

答案 0 :(得分:1)

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

一般来说,我不会担心它。

答案 1 :(得分: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告诉编译器生成汇编代码并停止。

然后查看汇编代码。

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

答案 2 :(得分:0)

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

但是,它取决于您使用的编译器以及优化设置。并且这里的任何差异都不太可能是快速程序和慢速程序之间的差异。

答案 3 :(得分:0)

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