使用开关或定义一组函数 - 哪个更快?

时间:2016-12-24 10:16:07

标签: c++ arrays performance switch-statement

这两个程序中哪一个运行得更快?第一个是指向重新分配变量的两个函数的指针数组,第二个是两个情况的开关,它们以相同的方式重新赋值变量。

1

#include <iostream>

void w (int &z);
void y (int &z);

int main(int argc, const char * argv[]) {
    void (*p[2]) (int &a) = {w,y};
    int s = 0;
    for(int i=0;i<1000;i++) {
        p[s](s);
    }
    return 0;
}

void w (int &z) {
    z = 1;
}

void y (int &z) {
    z = 0;
}

2:

#include <iostream>

int main(int argc, const char * argv[]) {
    int s = 0;
    for(int i=0;i<1000;i++) {
        switch (s) {
            case 0:
                s = 1;
                break;
            case 1:
                s = 0;
                break;
        }
    }
    return 0;
}

一般情况下,如果在编译时知道根据变量的当前值执行哪些指令,那么如果使用指向函数的指针数组而不是定义switch语句,程序运行得更快吗?或者switch语句更快?或者他们都一样快?

2 个答案:

答案 0 :(得分:1)

switch语句会更快,而且更容易理解。至少,在这种情况下。可能在大多数情况下。

在这种情况下,它会更快,因为编译器可以完全丢弃整个循环。很明显,所有代码只对局部变量产生影响,因此可以在不改变程序的可观察行为的情况下消除它。

这突显了为什么switch语句通常会更快。如果有很多情况,它将使用跳转表实现,并且编译器可以轻松获取所有信息,并且可以执行各种技巧来删除代码或者出于速度原因移动代码。

使用函数指针版本,编译器必须足够聪明才能意识到您正在使用函数指针初始化数组,然后永远不会更改它或将其地址传递给任何东西,以便其他任何东西都可以更改它。然后它还必须查看所有被调用的函数,并意识到它们对传入的引用没有任何影响。这是一个很多要求。

更糟糕的是,函数指针版本对于人类来说真的很难理解。如果您不关心这一点,为什么不用汇编语言或(甚至更好)用原始处理器操作码编写它?

答案 1 :(得分:1)

我认为switch语句会更快,因为函数指针具有查找函数和函数调用的开销。一个开关只是一个直接的跳台。