我尝试比较switch
语句和查找表的性能,如下所示。
这是使用switch
声明
#include <stdio.h>
int main()
{
int n = 3;
for (long i = 0; i < 10000000; ++i) {
switch (n) {
case 0:
printf("Alpha");
break;
case 1:
printf("Beta");
break;
case 2:
printf("Gamma");
break;
case 3:
printf("Delta");
break;
default:
break;
}
}
return 0;
}
以下是使用查找表的代码:
#include <stdio.h>
static char const * const Greek[4] = {
"Alpha",
"Beta",
"Gamma",
"Delta"
};
int main()
{
int n = 3;
for (long i = 0; i < 10000000; ++i) {
if (n >= 0 && n < 4) {
printf(Greek[n]);
}
}
return 0;
}
我在ubuntu 14.04,gcc版本4.8.4上运行两个程序,使用perf版本4.4.13来分析性能。结果:
我不知道为什么Switch Statement比Lookup表运行得慢。正如我所知,使用跳转表的Switch语句,我认为它应该比我的程序中的查找表运行得更快(它有额外的if语句)。
答案 0 :(得分:8)
如果使用优化进行编译,则代码没有开关,也没有查找表。我只是一个for循环,使用相同的固定字符串多次调用printf()
。任何最低限度合理的编译器实际上都会检测到n = 3
永远不会被更改并优化出来。也许你可以在循环内添加n = rand() % 4;
。
另一方面,如果你没有进行优化编译,那么采取时间是没有意义的。
提出你的问题,我希望查找表比switch语句更快,因为switch语句将完全颠覆分支预测,而if将没有问题,总是如此。
答案 1 :(得分:0)
您的基准测试完全不足以衡量printf()
/查找表的性能:几乎所有时间都花在switch
次调用中。如果{{1}} /查找表差异产生任何影响,由于总运行时间较长,测量噪声会相形见绌。
供参考:我希望在热,紧的循环中查找表只有大约十个时钟周期。在2 GHz CPU上,对于所有10000000次迭代,这只是0.05秒(粗略估计,很容易错误两倍,但这不会影响整体评估)。这是订单总运行时间的1%!