切换案例优化方案

时间:2010-08-24 17:49:30

标签: c

我知道各种切换案例的优化技术,但根据我的理解,大多数现代编译器并不关心如何编写切换案例,他们无论如何都会优化它们。

问题在于:

void func( int num)

set = 1,2,3,4,6,7,8,10,11,15

{
     if (num is not from set )
  regular_action();
     else
      unusual_stuff();
}

该集合总是具有上面提到的值或类似于许多元素紧密间隔的东西。

E.g。

set = 0,2,3,6,7,8,11,15,27是另一种可能的价值。

在我的程序运行期间,大多数时候传递的no不是来自此set,但是当它来自set时我需要采取一些操作。

我尝试使用以下函数模拟上述行为,以确定应该写入switch语句的方式。除了开关盒 - 跳转表 - 比较之外,下面的函数不做任何事情。

我需要确定compare_1是更快还是compare_2更快。在我的双核机器上,compare_2总是看起来更快,但我无法弄清楚为什么会发生这种情况?编译器是否如此智能以至于它在这种情况下也会优化?

5 个答案:

答案 0 :(得分:1)

感觉无法让一个功能比另一个更快。进行测量(没有printf)并比较生成的汇编程序(使用选项-S到编译器)。

答案 1 :(得分:1)

如果您的集合确实包含0到63范围内的数字,请使用:

#define SET 0x.......ULL
if (num < 64U && (1ULL<<num & SET)) foo();
else bar();

答案 2 :(得分:0)

以下是上述功能

#define MAX 100000000
void compare_1(void)
{
   unsigned long i;
   unsigned long j;
   printf("%s\n", __FUNCTION__);
   for(i=0;i<MAX;i++)
   {
      j = rand()%100;
      switch(j)
      {
    case 1:
    case 2:
    case 3:
    case 4:
    case 6:
    case 7:
    case 8:
    case 10:
    case 11:
    case 15:
       break   ;
    default:
       break   ;
      }
   }
}


void unreg(void)
{
   int i;
   int j;
   printf("%s\n", __FUNCTION__);
   for(i=0;i<MAX;i++)
   {
      j = rand()%100;
      switch(j)
      {
    default:
       break   ;
    case 1:
    case 2:
    case 3:
    case 4:
    case 6:
    case 7:
    case 8:
    case 10:
    case 11:
    case 15:
       break   ;
      }
   }
}

答案 3 :(得分:0)

以下是优化switch声明的一些建议:

删除switch语句

重新设计代码,以便不需要switch语句。例如,在基类中实现虚拟基本方法。或使用数组。

过滤掉常见的选择。如果范围内有多个选项,请将选项减少到范围中的第一项(尽管编译器可以自动为您执行此操作。)

保持选择连续

编译器很容易实现为单个索引跳转表。

许多选择,而不是连续的

一种方法是实现关联的数组(键,函数指针)。代码可以搜索表或更大的表,它们可以实现为链表。其他选择也是可能的。

几个选择,不连续

通常由编译器实现为if-elseif阶梯。

仿形

真正的证据是设置编译器优化开关和分析。

装配清单

您可能希望编写一些switch语句,并查看编译器如何生成汇编代码。查看哪个版本为您的情况生成最佳汇编代码。

答案 4 :(得分:0)

查看比较函数,第二个函数总是更快,因为它优化为始终执行默认语句。默认语句是执行&#34;按顺序&#34;因为它出现在开关中,所以在第二个功能中它会立即执行。每个开关都能为您提供相同的答案! 默认情况必须始终显示为交换机中的最后一种情况。见http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm 例如,它表示&#34;一个switch语句可以有一个可选的默认情况,它必须出现在交换机的末尾。当没有任何情况属实时,默认情况可用于执行任务。默认情况下不需要中断。&#34;