【问题标题】:Should if(a&&b) take more time than if(a) if(b)?if(a&&b) 是否应该比 if(a) if(b) 花费更多的时间?
【发布时间】:2015-03-13 13:24:41
【问题描述】:

我使用以下简单的逻辑来回答这样一个question

1:   if(a)        // 1 operation
2:   if (b)       // 1 operation

1:  if(a && b) // 1, 1(&&), 1 => 3 operations. 

因此,2 个操作对 3 个,但在第一个示例中,编译器需要调用另一条指令来执行。

这个逻辑是真的吗? 它取决于编译器吗? 调用像 ; 这样的空指令会花费编译器一些显着的时间吗?

This 也讨论了同样的问题,但没有考虑这个逻辑。 请帮助我们澄清这个问题。

【问题讨论】:

  • 我认为它们没有什么不同,性能取决于使用情况。如果您在第二种类型之前使用第一种类型,那么第一种类型将花费更多时间,反之亦然。基本上两者都是一样的。
  • 如果是 && 运算符,如果 a 被传递,那么 b 根本不会被计算。它的短路。
  • 等等...只是检查一下。我们是在谈论运行速度还是编译速度?您使用了诸如“是否调用空指令...花费编译器一些明显的时间”之类的短语,但我不禁认为您在谈论运行时.
  • @TiyebBellal 为什么编译速度很重要?编译中的任何差异都将是微小的,并且只会出现一次。
  • @muasif80 如果它不检查 b 那将是 ||而不是 &&

标签: java c# native


【解决方案1】:

有两种方法可以准确地回答这样的问题

1.) 查看 IL 代码(和/或)汇编代码生成并计算执行此代码所需的 CPU 周期(提示:这不适合初学者)

2.) 构建一个小测试程序,它会大量执行这两种变体,使用 StopWatch() 创建一个有用且可读的计时输出,运行几次。

3.) 推测一下你认为编译器的优化步骤能做什么,这个软件会做什么,和别人争论几个小时

【讨论】:

  • 如果您只是解释如何获得答案,我不确定它是否算作答案。不过,这是很有趣的信息。
  • @Duncan 给一个人一条鱼,你喂他一天;教一个人钓鱼,你就可以养他一辈子
【解决方案2】:

我假设编译器会为您的两种情况生成相同的字节码。所以我用两个不同的源文件对此进行了测试:

public class Test1 {    
  public static void main(String[] args) {
    if (args[0].equals("a"))
      if (args[1].equals("b"))
        System.out.println("Foo");
  }    
}

还有……

public class Test2 {    
  public static void main(String[] args) {
    if (args[0].equals("a") && args[1].equals("b"))
      System.out.println("Foo");
  }    
}

javap -c Test1等检查它们的字节码,结果是一样的:

公共静态无效主(java.lang.String[]); 代码: 0:aload_0 1:iconst_0 2:加载 3: ldc #2 // 字符串 a 5: invokevirtual #3 // 方法 java/lang/String.equals:(Ljava/lang/Object;)Z 8:如果当量 30 11:加载_0 12:iconst_1 13:加载 14: ldc #4 // 字符串 b 16: invokevirtual #3 // 方法 java/lang/String.equals:(Ljava/lang/Object;)Z 19:如果当量 30 22: getstatic #5 // 字段 java/lang/System.out:Ljava/io/PrintStream; 25: ldc #6 // 字符串 Foo 27: invokevirtual #7 // 方法 java/io/PrintStream.println:(Ljava/lang/String;)V 30:返回

因此,性能将是相同的。虽然如果有人能想到一个产生不同字节码的例子,我欢迎 cmets。

我的结果是使用 Java 1.7 中的 Oracle 的 javac。其他编译器的结果可能会有所不同,尽管我怀疑它们不会适用于这种情况。

【讨论】:

    【解决方案3】:

    有两种方法可以考虑您的问题:

    1. Java 语言定义

      • 语言定义第二个示例将使用短路执行,这意味着如果if 语句包含任何代码,第二个示例可能会执行得更快
    2. JVM 优化

      • JVM 运行时将删除死代码块,如果它可以证明它们没有任何副作用

    【讨论】:

    • 你的第一个论点对我来说没有意义。在第一个示例中,代码结构隐含了短路执行。你的第二个论点没有多大意义,除非你能解释你认为我们在这里有哪些死代码块?
    猜你喜欢
    • 1970-01-01
    • 2016-01-13
    • 2018-01-29
    • 1970-01-01
    • 2015-06-15
    • 2014-08-12
    • 2019-11-02
    • 2013-01-09
    • 1970-01-01
    相关资源
    最近更新 更多