首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >简化/优化一段条件组合的代码的最佳方式是什么?

简化/优化一段条件组合的代码的最佳方式是什么?
EN

Stack Overflow用户
提问于 2014-04-19 05:04:12
回答 5查看 1.3K关注 0票数 15

我有一段代码,我想优化可读性、性能和酷度。现在我有一个丑陋的东西:

代码语言:javascript
复制
if      ( cond1 &&  cond2 &&  cond3 && !cond4)
{
     // do something 
}
else if ( cond1 &&  cond2 && !cond3 &&  cond4)
{
    // do something 
}
else if ( cond1 && !cond2 &&  cond3 &&  cond4)
{
   // do something 
}
else if (!cond1 &&  cond2 &&  cond3 &&  cond4)
{
    // do something 
}
else
{
    // do something 
}

其中,cond1cond2cond3cond4是在上述代码块之前初始化的布尔值。我想让它变得更快,不那么丑陋,更酷。

我正在考虑这样做:

代码语言:javascript
复制
int val = (cond1 ? 0 : 1) + 2 * (cond2 ? 0 : 1) + 4 * (cond3 ? 0 : 1) + 8 * (cond4 ? 0 : 1);
if (val == 8)
{
    // do something
}
else if (val == 4)
{
    // do something 
}
else if (val == 2)
{
    // do something
}
else if (val == 1)
{
    // do something
}
else
{
    // do something 
}

这是有效的还是有缺陷的?有没有更好的方法?在查看多个条件的不同组合时,实现预期结果的典型方法是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-04-19 05:20:26

好的,最令人愉快的方式可能是

代码语言:javascript
复制
if(cond1 + cond2 + cond3 + cond4 == 3)
{
    if(!cond1)
    {
        // do something
    }
    else if(!cond2)
    {
        // do something
    }
    else if(!cond3)
    {
        // do something
    }
    else // !cond4
    {
        // do something
    }
}
else
{
    // do something
}

不过,我对那些不在数组中的值很谨慎。

票数 16
EN

Stack Overflow用户

发布于 2014-04-19 09:36:07

无论以何种方式,您都希望将值放入位标志中。也就是说,您需要为每个条件设置一个位或不设置为整数类型。那么在你的例子中,每个4位的值都代表了上面的ANDed条件之一。在此之后,您可以使用switch语句。可以说,它的可读性更好,而且编译器通常可以将其优化为跳转表。也就是说,它只会通过查找表中的某个值或类似的东西来偏移您的程序计数器,您不再需要检查每个值的组合。这样,你对ANDed案例的检查就变成了恒定的时间,而不是线性的,也就是说,如果你增加了4个标志,现在有256个组合,而不是16个组合,这种方法将以一种大-哦的方式同样快。或者,如果您不信任编译器将switch语句转换为跳转表,您可以自己使用flags值作为函数指针数组的索引。同样值得注意的是,ORed枚举值是在编译时折叠或预先计算的。

代码语言:javascript
复制
  enum {
    C1 = 0x1,
    C2 = 0x2,
    C3 = 0x4,
    C4 = 0x8
  };

  unsigned flags = 0;
  flags |= cond1 ? C1 : 0x0;
  flags |= cond2 ? C2 : 0x0;
  flags |= cond3 ? C3 : 0x0;
  flags |= cond4 ? C4 : 0x0;

  switch (flags) {
    case 0: // !cond1 && !cond2 && !cond3 && !cond4
      // do something
      break;
    case C1: //  cond1 && !cond2 && !cond3 && !cond4
      // do something
      break;
    case C2: // !cond1 &&  cond2 && !cond3 && !cond4
      // do something
      break;
    case C1 | C2: //  cond1 &&  cond2 && !cond3 && !cond4
      // do something
      break;
    case C3: // !cond1 && !cond2 &&  cond3 && !cond4
      // do something
      break;
    case C1 | C3: //  cond1 && !cond2 &&  cond3 && !cond4
      // do something
      break;
    case C2 | C3: // !cond1 &&  cond2 &&  cond3 && !cond4
      // do something
      break;
    case C1 | C2 | C3: //  cond1 &&  cond2 &&  cond3 && !cond4
      // do something
      break;
    case C4: // !cond1 && !cond2 && !cond3 &&  cond4
      // do something
      break;
    case C1 | C4: //  cond1 && !cond2 && !cond3 &&  cond4
      // do something
      break;
    case C2 | C4: // !cond1 &&  cond2 && !cond3 &&  cond4
      // do something
      break;
    case C1 | C2 | C4: //  cond1 &&  cond2 && !cond3 &&  cond4
      // do something
      break;
    case C3 | C4: // !cond1 && !cond2 &&  cond3 &&  cond4
      // do something
      break;
    case C1 | C3 | C4: //  cond1 && !cond2 &&  cond3 &&  cond4
      // do something
      break;
    case C2 | C3 | C4: // !cond1 &&  cond2 &&  cond3 &&  cond4
      // do something
      break;
    case C1 | C2 | C3 | C4: //  cond1 &&  cond2 &&  cond3 &&  cond4
      ; // do something
  };

另外,这也涵盖了所有的组合。如果您只需要一些子集,请随意删除其中的一些案例。编译器非常擅长优化switch语句。它可能比任何聪明的特殊情况下的算术技巧都要快。

代码语言:javascript
复制
  enum {
    C1 = 0x1,
    C2 = 0x2,
    C3 = 0x4,
    C4 = 0x8
  };

  unsigned flags = 0;
  flags |= cond1 ? C1 : 0x0;
  flags |= cond2 ? C2 : 0x0;
  flags |= cond3 ? C3 : 0x0;
  flags |= cond4 ? C4 : 0x0;

  switch (flags) {
    case C1 | C2 | C3: //  cond1 &&  cond2 &&  cond3 && !cond4
      // do something
      break;
    case C1 | C2 | C4: //  cond1 &&  cond2 && !cond3 &&  cond4
      // do something
      break;
    case C1 | C3 | C4: //  cond1 && !cond2 &&  cond3 &&  cond4
      // do something
      break;
    case C2 | C3 | C4: // !cond1 &&  cond2 &&  cond3 &&  cond4
      // do something
      break;
    default:
      // do something
      ;
  };
票数 25
EN

Stack Overflow用户

发布于 2014-04-19 05:15:15

将最有可能为假的条件放在左边,如果不检查其余条件,它将继续执行另一个条件,因此您在所谓的短路中获得了性能收益

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23162309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档