【问题标题】:Optimizing switch constructions - how to avoid adding if-clauses [closed]优化开关结构 - 如何避免添加 if 子句 [关闭]
【发布时间】:2014-09-19 15:41:04
【问题描述】:

我正在尝试优化我必须重构的代码。没有任何优化的代码会有一些 switch 语句。如果 switch 语句内部发生错误,则向调用方法返回错误,例如:

switch(var)
{ 
    case VAL1: 
    //do something... 
    break; 
    case VAL2: 
    //do something else... 
    //... 
    case VAL3: 
    if (...) // there is any case that can cause error 
    { 
         return error1;
    }
    break; 
    case VAL4: 
    if (...) // there is any case that can cause error 
    { 
         return error2;
    }
    break;
    case VAL5: 
    if (...) // there is any case that can cause error 
    { 
         return error1;
    }
    break;
    //and so on... 
    default: 
         break; 
} 

我正在重构代码,所以我没有在 switch 语句中返回错误,而是标记变量中存在错误:

int error_type = -1; 

switch(var)
{ 
    case VAL1: 
    //do something... 
    break; 
    case VAL2: 
    //do something else... 
    //... 
    case VAL3: 
    if (...) // there is any case that can cause error 
    { 
         error_type = error1;
    }
    break; 
    case VAL4: 
    if (...) // there is any case that can cause error 
    { 
         error_type = error2;
    }
    break;
    case VAL5: 
    if (...) // there is any case that can cause error 
    { 
         error_type = error1;
    }

    break;
    //and so on... 
    default: 
         break; 
}

if (error_type != -1) 
       return error_type; 

当没有错误时会出现问题,因为我们正在添加另一个 if 语句,如果该方法每秒被调用多次,这可能会导致性能问题。我想避免每次都检查条件。有什么建议可以改进此代码吗?有什么开关重构技巧吗?

//编辑:我知道这个例子可能看起来很愚蠢(因为那里的重构看起来不是很有用)但我正在重构的实际代码确实需要它(相信我)所以我尽量不降低性能在最终代码中。

【问题讨论】:

  • var 的可能值是什么?
  • if条件有什么共同点吗?
  • 和最重要的。你确定你需要优化吗?探查器怎么说?
  • 假设 var 来自一组 20 个小整数,Thomas 建议使用数组进行优化是一个很好的建议。但是,鉴于您所展示的重构,如果您看到任何可观察到的性能变化,我会感到震惊。如果 "many" in :many times per second" 小于 10 亿,那么请放松并尽可能编写最干净、最漂亮、最可维护的代码。
  • 您到底为什么认为这会导致性能问题?在 CPU 几乎肯定会正确预测的情况下测试局部变量的值,很容易证明其影响几乎为零。

标签: c++ c performance optimization refactoring


【解决方案1】:

一般的经验法则是switch 语句可以替换为查找表或数组。这些表的一个优点是它们可以很容易地以非常低的性能成本和对查找函数(引擎)的少量修改进行更新。

这里有一些想法:

如果有条件检查的模式,将变量放入表中。让引擎执行检查。

将函数指针放入表中以执行检查。如果函数指针为NULL,则不进行检查。

【讨论】:

  • 然而,if (table[x] != NULL) table[x]();switch(x)if (...) 的性能可能是“负数”或“零” - 除非你能以某种方式消除复杂的 if (...) - 然而,我疑。确实有使用 table 而不是 switch 的情况,但我认为这不是其中之一。
  • @MatsPetersson:在这种情况下,切换到表查找可能不会获得性能,但 OP 还提到了一个维护问题,即总是将案例添加到 switch 语句中。查找表擅长减少维护问题。
  • 对我来说,这几乎是一样的努力......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
  • 2022-01-07
相关资源
最近更新 更多