我正在尝试找出如何在
if ... else if ... else ...
中编写最优化的 C++
语句。
假设我们基于某些
n
变量值有 3 个可能的条件:n = 0
、0 < n < 100
和 n = 100
。我们假设 n = 0
将出现在 1%
情况、0 < n < 100
– 90%
和 n = 100
– 9%
中。注意,if ... else if ... else ...
会被执行多次,并且n
每次的值都会不同。
我的第一个假设是将条件按降序排列(最频繁的 - 第一个,最不频繁的 - 最后),如下所示。然而,第一个条件将有 3 个布尔表达式。由于第一个条件将始终被执行(在
100%
情况下)并且它由 3 个布尔表达式(>
、<
和 &&
)组成,因此这 3 个表达式将在 100%
情况下执行。 (也许编译器会进行一些优化,以某种方式减少到2个表达式。)第二个条件将在10%
情况下执行,第三个条件将在1%
情况下执行。
因此,假设会有
1 000
迭代,就会有 3 100
布尔表达式被求值 (3 000 + 100
)。
if ((n > 0) && (n < 100)) { // 3 boolean expressions will be executed in 100% cases.
...
} else if (n == 100) { // 1 additional boolean expression – in 10% cases.
...
} else { // n = 0 // No additional boolean expressions – in 1% cases.
...
}
如果改变条件的顺序(以便用3个布尔表达式消除条件),将会有
1 910
布尔表达式被评估(1 000 + 910
)。
if (n == 100) { // 1 boolean expression will be executed in 100% cases.
...
} else if (n == 0) { // 1 additional boolean expression – in 91% cases.
...
} else { // 0 < n < 100 // No additional boolean expressions – in 90% cases.
...
}
我理解对了吗?如果不是,如何使用
if ... else if ... else ...
正确优化代码以提高速度?
您的一项计数已结束。你说:
if ((n > 0) && (n < 100)) { // 3 boolean expressions will be executed in 100% cases.
但是(1)
&&
不是布尔表达式,而是隐式if
,因为它短路了表达式,并且(2)由于短路,后半部分n < 100
将仅执行99%的案例。 100% 的情况下只会检查n > 0
。
除此之外,您过于关注评估条件的频率。这是次要问题,因为首先要注意的是,在输入最频繁的分支之前,不可避免地要检查two条件。
考虑到这一点,您现在可以开始询问是否可以避免以更高的概率检查这两个条件之一。条件是
n > 0
(1% 的情况下为假)和 n < 100
(10% 的情况下为假)。现在,如果你先检查 n > 0
,那么你可以在 1% 的情况下避免检查其他项,但是当你先检查 n < 100
时,那么你可以在 10% 的情况下避免检查其他项。所以,这就是你应该做的:
if (n == 100) { // get 10% of the cases out of the way
...
} else if (n == 0) { // unavoidable second check after first check failed
...
} else { // most frequent case needs both checks
...
}
(假设 [0 ... 100] 是
n
唯一可以取的值。)