【问题标题】:Replace switch/case by #ifdef or something similar用 #ifdef 或类似的东西替换 switch/case
【发布时间】:2018-07-06 13:40:41
【问题描述】:

我正在尝试用其他工具替换 switch/case 结构做同样的事情但性能更好(更少的执行时间......),我想到了#ifdef 方法,但我不知道如何在这种情况下使用它:

float k_function(float *x,float *y,struct svm_model model)
{
    int i;
    float sum=0.0;
    switch(model.model_kernel_type)  
    {
    case LINEAR :
        return result1;
    case POLY :
        return result2;
    case RBF :
        return result3;
    case SIGMOID :
        return result4;
    default :
        return 0;
    }
}

PS:

typedef   enum   kernel_type   {LINEAR, POLY, RBF, SIGMOID};

【问题讨论】:

  • 在尝试 nanoptimizations 之前,您最好了解编译器和预处理器之间的区别以及各自的功能。
  • 除非model.model_kernel_type 是在编译时定义的常量,否则您将无法使用预处理器条件。看起来不像。
  • 您确定需要更好的性能吗?如果是这样,您确定更改这段代码会给您带来所需的性能提升吗? IE。你测量过这个吗?
  • 您是否真正分析过您的代码的性能并确定这个switch 语句实际上是一个性能问题?

标签: c switch-statement conditional-compilation


【解决方案1】:

正如我已经评论过的,我不相信预处理器语句是您正在寻找的。要使用预处理器条件,model.model_kernel_type 需要是使用 #define 语句定义的常量。

我不知道 switch 语句的内部结构,因为它可能是 O(n) 或 O(1),具体取决于编译器如何处理它。如果您需要确定 O(1) 时间复杂度,您可以简单地将 switch 语句替换为如下查找表:

float model_type_results[4] = {result1, result2, result3, result4};

...

return model_type_results[model.model_kernel_type];

【讨论】:

  • 谢谢。我最近经常在 C 和 python 之间来回穿梭。
  • 无论如何,一个体面的优化器可能会生成与此非常相似的代码。
  • 我注意到这不会比原来的switch 语句快。除非有一些非常好的优化,否则每次调用函数都必须初始化小型查找数组。您可以通过将其设为static 来避免这种情况,但这意味着额外的内存查找和取消引用。这绝对是 OP 实际上应该进行基准测试的一个选项,但我怀疑原始的 switch 语句在性能方面很难被击败。特别是如果原来的实际上只有四个案例。
  • @GemTaylor 根据我的经验,不,不一定。这需要空间,除非明确指示,否则优化器通常不会决定权衡。
  • 如果覆盖范围内的所有可能值,则跳转表和跳转代码可以小于等效的条件语句链。编译器是否可以推断出跳转可以进一步优化为调用,我不知道,但我认为这是一个简单的权衡,尽管非常具体。
【解决方案2】:

我想问题不只是 1 个 case 语句,而是充斥着类似 case 语句的代码。

c++ 虚函数表是一个类似的概念,用于避免此类 case 语句在代码中激增。在 C 结构中实现函数表语义其实并不难。

传统上,它们被编写为成员函数指针,但如果每个类有很多对象,则使用单个每类函数表指针会更节省空间。

【讨论】:

    【解决方案3】:

    #ifdef 是编译时操作,而不是运行时操作。这不是您在这里寻找的解决方案。

    老实说,如果您的switch 仅包含四个案例,那么您可以做的改进不多。如果您在这里看到任何类型的放缓,那就是您的结果是如何计算的(您没有显示)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 2014-08-30
      • 2010-10-26
      • 1970-01-01
      相关资源
      最近更新 更多