惰性逻辑和临时值来提高表达式的可读性

Lazy logic and temporary values to improve the reading of an expression

本文关键字:表达式 可读性 逻辑和      更新时间:2023-10-16

很抱歉,我找不到一个更好的标题。

我习惯于编写布尔表达式,添加一些临时变量来提高表达式的可读性,换句话说,我不喜欢这样:

// Example 1
// hard to read and understand at first glance
if (value % 2 && value ^ weirdFlags &&
    (value > threshold) && (value < ceiling) &&
    /* lots of comparisions */)
{ /* do something*/ }

更喜欢这个:

// Example 2
// this is way easier to read and understand
const bool isEven = value % 2;
const bool flagsChecked = value ^ weirdFlags;
const bool inRange = (value > threshold) && (value < ceiling);
const bool foo = /* lots of comparisions */;
if (isEven && flagsChecked && inRange && foo)
{ /* do something*/ }

但是使用我最喜欢的编码风格时,我没有利用惰性逻辑优化,因为所有的临时值都被计算,而使用另一种编码风格时,只计算不可思议的值。

还有另一种解决方案,允许使用惰性逻辑优化并保持代码可读,那就是注释代码:

// Example 3
// this check test if the value is an even number
// and checks the value with the provided flags
// and assures that the value is in the required range
// and lots of additional comparisions
if (value % 2 && value ^ weirdFlags &&
    (value > threshold) && (value < ceiling) &&
    /* lots of comparisions */)
{ /* do something*/ }

但是,在代码开发过程中,当一组程序员日复一日地编写相同的源文件时,并不能保证代码注释与下面的代码匹配(并不是所有的程序员都关心良好的文档)。这就是为什么我更喜欢用一种简洁的方式来解释代码。

因此,最后,研究例2的情况,将临时值声明为const,仅在布尔表达式中使用它们,在表达式的同一作用域内并且靠近表达式本身,问题是:
  • 在示例2中,编译器是否会执行一些涉及临时值的优化,以提高布尔表达式(惰性求值)的性能?
  • 在你看来,这三个例子哪个是最正确的?为什么?

谢谢你的建议

看看这个:

if(const bool isEven = value % 2)
if(const bool flagsChecked = value ^ weirdFlags)
if(const bool inRange = (value > threshold) && (value < ceiling))
if(const bool foo = /* lots of comparisions */)
{
    /* do something*/
}

神奇!

我总是更喜欢可读性,而不是过早的优化,直到它被证明是性能瓶颈。

在这个例子中是例2。你还可以这样做:

bool Class::isSomething() {
  const bool isEven = value % 2;
  if(!isEven) return false;
  const bool flagsChecked = value ^ weirdFlags;
  if(!flagsChecked) return false;
  const bool inRange = (value > threshold) && (value < ceiling);
  if(!inRange) return false;
  const bool foo = /* lots of comparisions */;
  if(!foo) return false;
  return true;
}