以下是我需要优化和计划的代码,以便切换到最佳状态。但我可以比较一下。所以我计划将comaparision(len> 3)作为默认情况。
如果我将比较部分(len> 3)作为默认情况并在swith中添加默认值,它会更快吗?
或者如何将以下代码作为switch语句?
if ( len > 3 ) {
which will happen more often;
}
else if ( len == 3 ) {
next case which may occur often;
} else if ( len == 2 ) {
the next priority case;
} else {
and this case occurs rarely;
}
答案 0 :(得分:6)
可能不是。 if...else
和switch...case
都是高级构造。什么减慢你的速度是分支预测。预测越好,代码运行得越快。您应该将最常见的案例放在if
中,将else if
放在第二位,依此类推,就像您写的那样。对于switch
,结果取决于内部编译器实现,它可以对您的订单进行重新排序。实际应该为较少发生的情况保留default
,因为必须先检查其余条件,然后再回到default
。
总而言之,只要您按正确的顺序设置条件,if...else
在性能方面的使用就是最佳的。关于switch...case
它的特定编译器,取决于应用的优化。
另请注意,switch...case
比if...else
更受限制,因为它仅支持简单的值比较。
答案 1 :(得分:3)
虽然你已经接受了可能是最好的答案,但我想提供另一种选择。
请注意,标准警告适用 - 优化不是优化,除非您已经分析了代码。
但是,如果您遇到与分支相关的不良表现,您可以减少或消除它们。你的代码有一个或多个不等式比较并不是一个障碍 - 你可以将你的案例减少到一组直接的等式,如果有必要,用它来索引一个表,而不是分支。
void doSomething(int len)
{
static const char* str[] =
{ "%2d > 3\n",
"%2d < 2\n",
"%2d = 2\n",
"%2d = 3\n"
};
int m1 = (len-2)>>31;
int m2 = (len-4)>>31;
int r = (len & m2 & ~m1) + !!m1;
printf(str[r],len);
}
请注意,这些代码做了一些假设,这些假设在实践中可能无法实现,但是我们正在做出这样的假设,即首先需要优化......
另外,请注意,通过更多地了解输入参数的实际范围和类型,以及实际采取的操作需要,可以实现更好的优化。
答案 2 :(得分:2)
你无法将比较移动到switch语句中..它使用单一检查进行选择..即:
switch (len) {
case 1:
// do case 1 stuff here
break;
case 2:
// do case 2 stuff here
break;
case 3:
// do case 3 stuff here
break;
}
使用中断来防止案例陈述相互碰撞了解更多here
您的代码是“优化的”,因为它将处于当前状态..
答案 3 :(得分:1)
如果您担心速度问题,事实是您的if...else
或switch...case
语句不会对您的申请速度产生实际影响,除非您有数百个。丢失速度的地方在迭代或循环中。要专门回答您的问题,您无法将if...else
语句转换为switch...case
语句,而default
首先出现;但话虽如此,如果你确实转换为switch...case
,那么你将会以相同的速度运行(差异太小,无法通过传统的基准测试工具获取)。
答案 4 :(得分:1)
你要知道的唯一方法就是用它来衡量它 编译器。如果性能有问题,您应该使用该选项 为编译器提供探查器输出,让它决定; 它通常会找到最佳解决方案。 (注意即使在 像英特尔这样的特定架构,就其而言是最佳解决方案 机器指令可能因处理器而异 接下来。)
在您的情况下,开关可能看起来像:
switch ( len ) {
case 2:
// ...
break;
case 3:
// ...
break;
default:
if ( len > 3 ) {
// ...
} else {
// ...
}
}
只有两个有效的情况,编译器没有多少
与...合作。一个典型的实现(没有极端
优化)将进行边界检查,然后进行表查找
两个明确的案例。然后任何体面的编译器都会接受
您default
案例中的比较对应于其中一项
它已经完成的边界检查,而不是重复它。
但只有两种情况,跳转表可能不会
与两次比较相比有显着差异,
尤其是在最常见的情况下,你将会出类拔萃。
直到你有实际的探查器信息 代码中的瓶颈,我不担心。一旦您 有了这些信息,您可以查看不同的变体 哪个更快,但我怀疑如果你使用最大值 优化和Feed分析信息重新进入 编译器,没有区别。
答案 5 :(得分:0)
您可以在案例中使用范围:
switch (len) {
case 3 ... INT_MAX:
// ...
break;
case 2:
// ...
break;
default:
// ...
break;
}
编辑:但这是GCC提供的扩展......