【问题标题】:Is there something faster than a switch statement?有什么比 switch 语句更快的吗?
【发布时间】:2013-12-02 10:27:27
【问题描述】:

在优化性能时,到目前为止,我一直认为没有什么比 switch 语句更快的了。这是绝对的真理吗?

【问题讨论】:

  • 是的,这是绝对真理。
  • @MichaelPetrotta: 一些 NOP 比其他的更快 =P
  • @leemo,大概,OP 已经明白 if 语句是在 slower-than 方面,而不是 faster-than 方面。
  • @MichaelPetrotta 确实如此。

标签: performance language-agnostic switch-statement


【解决方案1】:

没有什么比最优算法更快的了(实际上,没有什么比最优算法更快了)。涉及 switch 与 if 的微优化很少会对现代系统产生重大改进。 但是,在有限的情况下(以及在较旧的计算机上),Duff's device 之类的东西很有价值(例如,大约 1983 年的计算机在寄存器数量极其有限的计算机上进行计算机动画处理)。

【讨论】:

    【解决方案2】:

    switch 语句的核心是一系列跳转,这意味着 O(n) 性能。可以将哈希表用作跳转表,从而导致 O(1) 性能。不幸的是,除了身份之外,很少有散列算法可以与一系列跳转一样快或更快,并且仍然提供识别要检查的散列条目所需的唯一散列值。

    【讨论】:

      【解决方案3】:

      我做了这个测试:

      #include <stdio.h>
      #include <time.h>
      
      int SwitchBase(int x)
      {
          int TheReturn=22;
          switch (x)
          {
          case 1:
              TheReturn=1;
              break;
          case 2:
              TheReturn=2;
              break;
          case 3:
              TheReturn=3;
              break;
          case 4:
              TheReturn=4;
              break;
          case 5:
              TheReturn=5;
              break;
          case 6:
              TheReturn=6;
              break;
          case 7:
              TheReturn=7;
              break;
          case 8:
              TheReturn=8;
              break;
          case 9:
              TheReturn=9;
              break;
          case 10:
              TheReturn=10;
              break;
          default:
              TheReturn=0;
          }
          return TheReturn;
      }
      
      int BitwiseBase(int x)
      {
          int TheReturn=22;
          TheReturn=
          ((((!(x^1))<< 31) >> 31) &1)
          |(((((x^1)&&(!(x^2)))<< 31) >> 31) &2)
          |(((((x^1)&&(x^2)&&(!(x^3)))<< 31) >> 31) &3)
          |(((((x^1)&&(x^2)&&(x^3)&&(!(x^4)))<< 31) >> 31) &4)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(!(x^5)))<< 31) >> 31) &5)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(!(x^6)))<< 31) >> 31) &6)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(x^6)&&(!(x^7)))<< 31) >> 31) &7)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(x^6)&&(x^7)&&(!(x^8)))<< 31) >> 31) &8)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(x^6)&&(x^7)&&(x^8)&&(!(x^9)))<< 31) >> 31) &9)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(x^6)&&(x^7)&&(x^8)&&(x^9)&&(!(x^10)))<< 31) >> 31) &10)
          |(((((x^1)&&(x^2)&&(x^3)&&(x^4)&&(x^5)&&(x^6)&&(x^7)&&(x^8)&&(x^9)&&(x^10))<< 31) >> 31) &0);
          return TheReturn;
      }
      
      int main()
      {
          int randomnumber=23;
          int checknum=24;
          clock_t start, diff;
          srand(time(0));
          start = clock();
          for(int i=0;i<1000000;i++)
          {
              randomnumber = rand() % 11;
              checknum=SwitchBase(randomnumber);
              if (checknum!=randomnumber)
              {
                  printf("s %i and %i",checknum,randomnumber);
              }
          }
          diff = clock() - start;
      
          int msec = diff * 1000 / CLOCKS_PER_SEC;
          printf("SwitchBase Time taken %d milliseconds", msec);
      
          start = clock();
          for(int i=0;i<1000000;i++)
          {
              randomnumber = rand() % 11;
              checknum=BitwiseBase(randomnumber);
              if (checknum!=randomnumber)
              {
                  printf("b %i and %i",checknum,randomnumber);
              }
          }
          diff = clock() - start;
      
          msec = diff * 1000 / CLOCKS_PER_SEC;
          printf("BitwiseBase Time taken %d milliseconds", msec);
      
          return 0;
      }
      

      使用代码块和检查了 -O2 的 gcc 编译器。 结果: SwitchBase 耗时 15 毫秒BitwiseBase 耗时 31 毫秒。 所以在这种情况下,Switch 仍然比按位更快。

      【讨论】:

        猜你喜欢
        • 2015-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-15
        • 2017-04-03
        • 2015-07-20
        • 2011-11-07
        • 1970-01-01
        相关资源
        最近更新 更多