【问题标题】:What is the different in putting most possible true condition in if, else-if or else将最可能的真实条件放入 if、else-if 或 else 有什么不同
【发布时间】:2014-09-01 11:51:01
【问题描述】:

将最可能的条件放在 if、else-if 或 else 条件中是否有任何区别

例如:

int[] a = {2,4,6,9,10,0,30,0,31,66}
int firstCase = 0, secondCase = 0, thirdCase = 0;
for( int i=0;i<10;i++ ){
    int m = a[i] % 5;
    if(m < 3) {
        firstCase++;
    } else if(m == 3) {
        secondCase++;
    } else {
        thirdCase++;
    }
}

执行时间和输入有什么区别

int[] a = {3,6,8,7,0,0,0,0,0,0}

【问题讨论】:

  • 对于时间复杂度,您通常计算最坏情况的时间和介质。在最坏的情况下,您显然每次都会假设最复杂的路径将遵循。所以,回答你的问题,应该没什么区别。
  • 这是一个不好的例子,因为如果 n 为正数(包括 0),n % 2 将始终为 0 或 1。
  • 感谢@Dici,现在我更正了代码,我现在正确了
  • 0 是偶数 (0 % 2 == 0) !一个数字只能是奇数或偶数,% 2 没有第三种情况。更好的例子是 % 3。但是,它仍然是一个糟糕的例子,因为所有三种情况都有相同的概率。我将建议您进行修改。
  • @Dici - 我建议您阅读 JLS 第 15.17.3 节。还有第三种情况。

标签: java time-complexity execution


【解决方案1】:

将最可能的真实条件放在 if、else-if 或 else 条件中有什么不同

实际上,Java 的答案是“视情况而定”。

您会看到,当您运行 Java 代码时,JVM 通过使用解释器开始并收集统计信息。可以记录的统计数据之一是最常采用分支指令中的哪条路径。这些统计信息可以被 JIT 编译器用来影响代码重新排序,这不会改变编译代码的语义。

因此,如果您要使用两个不同的数据集(即“大部分为零”和“大部分非零”)执行代码,JIT 编译器可能会以不同方式编译代码。

它是否真的可以进行这种优化取决于它是否可以确定重新排序是有效的。例如,是否可以推断出被测试的条件是互斥的?


那么这对复杂性有何影响?好吧......让我们为您的简化示例求和,假设 JIT 编译器没有做任何“智能”的事情。并假设我们不只是处理长度为 10 的数组(这使得对复杂性的讨论变得毫无意义)。

考虑一下:

  • 对于每个零,循环执行一次测试和一次增量 - 比如说 2 次操作。

  • 对于每个非零元素,循环执行两次测试和一次增量 - 比如说 3 次操作。

因此,当所有元素都为零时,对于 N 个元素来说,这大约是 2*N 次操作,而在所有非零时,则为 3*N 次操作。但两者都是O(N) ...所以大O复杂度不受影响。

(好吧,我遗漏了一些东西......但你明白了。其中一种情况会更快,但复杂性不受影响。)

【讨论】:

  • 复杂性部分是否相关?如果他在其中一个案例中有一个从 0 到 n - 1 的循环,则复杂性将不一样。然而,它与 if/else-if 语句的顺序无关。
  • @Dici - OP 将问题标记为“时间复杂性”,因此对复杂性的讨论显然是相关的。这就是你争论的重点吗?
【解决方案2】:

这比你被告知的要多一些。

  1. 'if' 与 'else':如果一个条件及其相反的可能性不相等,您应该在 'else' 块中处理更有可能的条件,而不是 'if' 块。 “if”块需要一个不被执行的条件跳转和一个围绕“else”块的最终分支; 'else' 块需要一个条件分支,它完全没有最终分支。

  2. 'if' vs 'else if' vs 'else':显然,您应该处理 'if' 块中最常见的情况,以避免第二次测试。与 (1) 相同的考虑决定了最终的 'else if' 和最终的 'else' 之间更常见的情况应该在最终的 'else' 块中处理。

话虽如此,除非测试不平凡,或者所有这些块的内容完全不重要,否则任何测试都不太可能产生明显的差异。

【讨论】:

  • 你的第一点引起了我的注意,但我不明白。什么叫最终分支,为什么它比条件跳转慢(如果我理解不好的话)?
  • @Dici 条件分支加无条件分支比条件分支慢。
【解决方案3】:

如果你只有一个if-else 没有区别,因为条件总是会被评估,它几乎总是真或假都没有关系。但是,如果您在else 部分(else if)中有一个if,最好将最可能的真实条件放在第一个if 中。因此,大多数时候您不需要评估 else 中的条件,从而提高性能。

【讨论】:

    【解决方案4】:

    如果 if 中的大多数条件都为真,那么执行时间会更少。因为在第一个 if 条件下,只有它满足。

    如果 if-else 中的大多数条件都为真,那么执行时间将比最后一个场景少,比第一个场景多。

    如果大多数条件在 else 中为真,那么执行时间会更长。因为它会检查前 2 个条件。

    【讨论】:

      【解决方案5】:

      确实如此。

      if ... else if ... 检查按其编码顺序进行。因此,如果您将最可能的条件放在此条件检查队列的末尾 - 这样的代码会运行得稍微慢一些。

      但这一切都取决于这些条件是如何构建的(它们有多复杂)。

      【讨论】:

        【解决方案6】:

        最可能的条件应该是 if 和 then if else 等等。

        【讨论】:

          【解决方案7】:

          最好将最常见的条件写在第一级,这样如果条件为真或假,将在更短的时间内首先处理。

          如果您将最常见的条件放在中间 (else..if) 或最后 (else) 中,则到达该条件语句需要时间,因为它需要检查每个条件语句。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-01
            • 2021-03-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多