这两个程序中哪一个运行得更快?第一个是指向重新分配变量的两个函数的指针数组,第二个是两个情况的开关,它们以相同的方式重新赋值变量。
#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;
}
#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语句更快?或者他们都一样快?
答案 0 :(得分:1)
switch
语句会更快,而且更容易理解。至少,在这种情况下。可能在大多数情况下。
在这种情况下,它会更快,因为编译器可以完全丢弃整个循环。很明显,所有代码只对局部变量产生影响,因此可以在不改变程序的可观察行为的情况下消除它。
这突显了为什么switch
语句通常会更快。如果有很多情况,它将使用跳转表实现,并且编译器可以轻松获取所有信息,并且可以执行各种技巧来删除代码或者出于速度原因移动代码。
使用函数指针版本,编译器必须足够聪明才能意识到您正在使用函数指针初始化数组,然后永远不会更改它或将其地址传递给任何东西,以便其他任何东西都可以更改它。然后它还必须查看所有被调用的函数,并意识到它们对传入的引用没有任何影响。这是一个很多要求。
更糟糕的是,函数指针版本对于人类来说真的很难理解。如果您不关心这一点,为什么不用汇编语言或(甚至更好)用原始处理器操作码编写它?
答案 1 :(得分:1)
我认为switch语句会更快,因为函数指针具有查找函数和函数调用的开销。一个开关只是一个直接的跳台。