在Switch案例中默认

以下是我需要优化和计划的代码,以便切换到最佳状态。 但我可以比较一下。 所以我计划将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; } 

可能不是。 if...elseswitch...case都是高级构造。 什么减慢你的速度是分支预测。 预测越好,代码运行得越快。 你应该把你最常见的情况放在第一位, if是第二位,就像你写的那样,依此类推。 对于switch ,结果取决于内部编译器实现,尽管您自己的订单可以重新排序。 实际上应该为较少发生的情况保留default因为在回退到default之前必须检查其余条件。

总而言之,只要您按正确的顺序设置条件, if...else性能使用就是最佳的。 关于switch...case它是编译器特定的,取决于应用的优化。

另请注意, switch...caseif...else更受限制,因为它仅支持简单的值比较。

虽然你已经接受了可能是最好的答案,但我想提供一个替代方案。

请注意,标准警告适用 – 优化不是优化,除非您已经分析了代码。

但是,如果您遇到与分支相关的不良性能,则可以减少或消除它们。 你的代码有一个或多个不等式比较并不是一个障碍 – 你可以将你的情况减少到一组直接的等式,如果有必要,用它来索引一个表,而不是分支。

 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); } 

请注意,这些代码做了几个假设,这些假设在实践中可能不成立,但是我们正在做出一个疯狂的假设,即首先需要进行优化……

此外,请注意,可以通过更多地了解输入参数的实际范围和类型以及实际采取的实际操作来实现更好的优化。

你不能将比较移动到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; } 

使用break来防止case语句相互碰撞在这里阅读更多内容

您的代码是“优化的”,因为它将处于当前状态。

您将要知道的唯一方法是使用您的编译器对其进行基准测试。 如果性能是一个问题,您应该使用该选项为编译器提供探查器输出,并让它决定; 它通常会找到最佳解决方案。 (请注意,即使在特定架构上,如英特尔,机器指令方面的最佳解决方案也可能因处理器而异。)

在您的情况下,开关可能看起来像:

 switch ( len ) { case 2: // ... break; case 3: // ... break; default: if ( len > 3 ) { // ... } else { // ... } } 

只有两个有效的情况,编译器没有太多工作。 典型的实现(没有极端优化)将进行边界检查,然后对两个显式情况进行表查找。 然后,任何体面的编译器都会认为default情况下的比较对应于它已经完成的一个边界检查,而不是重复它。 但是只有两种情况,跳转表可能与两次比较相比没有显着差异,特别是在最常见的情况下你会超出界限。

直到你有实际的探查器信息,这是你的代码中的瓶颈,我不会担心它。 获得该信息后,您可以分析不同的变体以查看哪个更快,但我怀疑如果您使用最大优化并将分析信息反馈到编译器中,则没有区别。

如果你担心速度,事实是你的if...elseswitch...case语句不会对你的应用程序速度产生真正的影响,除非你有数百个。 丢失速度的地方是迭代或循环。 要具体回答您的问题,您不能将if...else语句转换为switch...case语句, default首先出现; 但话说回来说,如果你确实转换成了一个switch...case那么你将会以相同的速度运行(差异太小,无法通过传统的基准测试工具获得)。

您可以在案例中使用范围:

 switch (len) { case 3 ... INT_MAX: // ... break; case 2: // ... break; default: // ... break; } 

编辑:但这是GCC提供的扩展……