代码之家  ›  专栏  ›  技术社区  ›  ENIAC

条件词在`if…中的顺序。。。否则如果。。。其他的在C中++

  •  -6
  • ENIAC  · 技术社区  · 1 年前

    我正试图找出如何写出最优化的 if ... else if ... else ... 中的声明 C++ .

    假设我们有3个可能的条件,基于 n 变量值: n = 0 , 0 < n < 100 n = 100 。让我们假设 n=0 将发生在 1% 案例, 0 < n < 100 90% n=100 9% 。请注意 如果…否则。。。其他的 将被执行多次,并且的值 n 每次都会有所不同。

    我的第一个假设是按降序排列条件(最频繁的第一个,最不频繁的最后一个),如下所示。但是,第一个条件将有3个布尔表达式。由于第一个条件将始终执行(在 100% case),并且它由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.
      ...
    }
    

    我理解得对吗?如果没有,如何使用正确优化代码 如果…否则。。。其他的 速度?

    使现代化 根据评论,做了一个测试。 The first variant 提供的编译代码行数少于 the second one 。我不懂汇编语言,所以我不确定在这种情况下少行是否更好。

    1 回复  |  直到 1 年前
        1
  •  2
  •   j6t    1 年前

    你的一个计数不正确。你说:

    if ((n > 0) && (n < 100)) {  // 3 boolean expressions will be executed in 100% cases.
    

    但是(1) && 不是布尔表达式,而是隐式表达式 if 因为它使表达式短路,以及(2)由于后半部分短路 n < 100 只有99%的案件会被执行。只有 n > 0 将在100%的病例中进行检查。

    除此之外,你过于关注频率 条件 评估。这是次要的问题,因为首先要注意的是,检查是不可避免的 可以输入最频繁分支之前的条件。

    考虑到这一点,您现在可以开始询问是否有可能以更高的概率避免检查这两个条件中的一个。条件是 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 可以接受。)