避免重复/循环非开关

时间:2016-02-02 18:29:03

标签: c optimization dry

我有一个紧密循环的热点代码:

for (i = 0; i < big; i++)
{
    if (condition1) {
        do1();
    } else if (condition2) {
        do2();
    } else {
        do3();
    }
    // Shared code goes here
    // More shared code goes here
}

由于condition1condition2是不变的,我将循环解开为

if (condition1) {
    for (i = 0; i < big; i++)
    {
        do1();
        // Shared code goes here
        // More shared code goes here
    }
} else if (condition 2) {
    for (i = 0; i < big; i++)
    {
        do2();
        // Shared code goes here
        // More shared code goes here
    }
} else {
    for (i = 0; i < big; i++)
    {
        do3();
        // Shared code goes here
        // More shared code goes here
    }
}

这样运行得更好,但我想知道如果不重复自己,是否有一种聪明的方法可以做到这一点?

2 个答案:

答案 0 :(得分:4)

另一个可能稍微高效的选项是使用宏来为您构建代码:

#define DO_N(name, ...) for(int i = 0; i < big; i++){name(__VA_ARGS__);/*shared code*/}

if (condition1) {
    DO_N(do1, .../*arguments here*/)
} else if (condition 2) {
    DO_N(do2, ...)
} else {
    DO_N(do3, ...)
}

#undef DO_N

它的丑陋,但我认为它可以做你想要的,并且可能允许内联函数指针不在哪里。

此外,您可能会发现将共享代码放在单独的宏或函数中更具可读性。

答案 1 :(得分:3)

我认为你可以声明一个函数指针和一些函数foo()

typedef void (*fp)(void);

void foo(int big, fp f) {
    for (int i = 0; i < big; ++i) {
        f();
        // Shared code goes here
        // More shared code goes her
    }
}

然后更改您的代码:

if (condition1) {
    foo(big, do1);
} else if (condition2) {
    foo(big, do2);
} else {
    foo(big, do3);
}