使用开关或定义函数数组 - 更快

Using a switch or defining an array of functions - which is faster?

本文关键字:数组 更快 函数 定义 开关      更新时间:2023-10-16

这两个程序中的哪一个运行速度更快?第一个是重新分配变量的两个函数的指针数组,第二个是以相同方式重新分配变量的两个情况。

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语句通常会更快。如果有很多情况,它将使用跳台进行实施,并且编译器将所有信息都触手可及,并且出于速度原因可以执行各种技巧来删除代码或将其移动。

>

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

甚至更糟糕的是,对于人类而言,功能指针版本确实很难理解。而且,如果您不在乎,为什么不使用汇编语言或(甚至更好)在原始处理器opcodes中编写它?