【问题标题】:java null check syntactical differencejava null 检查语法差异
【发布时间】:2013-06-17 08:43:25
【问题描述】:

迄今为止发布的任何 java 版本之间是否存在性能差异

foo != null

和

null != foo?

我个人认为上述两种形式的对象空值检查的行为没有任何变化,但不确定哪一种表现更好。我知道差异会非常小,如果有的话,但我想知道为什么有人以这种方式编写所有代码。

【问题讨论】:

  • 我不存在性能差异。如果有,应该很难衡量。
  • 应该没有性能差异,但形式可读性角度 foo != null 更好。因为通常在左侧,我们将要比较的值与右侧的值进行比较。通常我们会将我们的对象(如 foo)与 null 进行比较。从逻辑上讲,没有必要针对 foo 检查 null。
  • 有关尤达条件的更多信息,请参阅here。在某些 C 圈子中,它们作为一种避免意外赋值而不是比较的方法非常流行(编译器错误,因为常量不是左值)。性能方面,我会很惊讶地看到它们的表现不同。
  • 我发现了一个非常有趣的结果(在我的回答中有详细说明)。

标签: java performance optimization syntax null


【解决方案1】:

应该没有性能差异,但形式可读性 foo != null 更好。因为通常在左侧,我们将要比较的值与右侧的值进行比较。通常我们会将我们的对象(如 foo)与 null 进行比较。

【讨论】:

    【解决方案2】:

    这来自旧 C 时代。它以 foo == null (null == foo) 开头。

    在 c 中的语法是有效的(编译器没有抱怨):

    if (foo = null) {
    }
    

    为了防止这种微妙的错误语法开始使用:

    if (null == foo) {
    }
    

    因为 null 是常量 this 如果(空=富){ }

    变成语法错误。

    在 java 中只有一种情况很重要:

    boolean someBoolean;
    if (someBoolean = true) {
    }
    

    是运行时错误,但可以编译

    这个

    boolean someBoolean;
    if (true = someBoolean) {
    }
    

    是编译错误。

    没有性能问题,只是在某些情况下防止错误。

    【讨论】:

      【解决方案3】:

      Equality is symmetric。所以顺序在语义上并不重要。

      传统风格说你把你要检查的东西放在第一位,常数放在最后。这遵循(至少许多欧洲的)语言形式,例如“x 是空的吗?”不是 "is null x?"。

      在历史上的某一时刻,人们曾经用 C 编写 if (NULL == x)。这是为了让编译器通过说“你不能分配给常量”来捕获意外的语法错误 if (NULL = x)。标准代码质量工具现在可以识别这些类型的错误,因此这种做法现在已经过时了。

      【讨论】:

        【解决方案4】:

        时尚是关于尤达风格的。这只是个人喜好的问题。

        “尤达条件”——使用 if (constant == variable) 而不是 if (变量 == 常量),例如 if (4 == foo)。因为这就像说 “如果天空是蓝色的”或“如果男人是高大的”。

        More on SO

        【讨论】:

          【解决方案5】:

          不,这两种形式没有区别。

          不管怎样,有如下指令——加载foo的值,与0(null)比较,读取比较结果。

          现在,如果是 equals() 方法,那就不一样了:)

          【讨论】:

          • 比大多数人都好。
          【解决方案6】:
          public class Stack
          {
              public static void main(String[] args)
              {
                  Object obj0 = null;
                  Object obj1 = new Object();
                  long start;
                  long end;
                  double difference;  
                  double differenceAvg = 0;
          
                  for (int j = 0; j < 100; j++)
                  {
                      start = System.nanoTime();
          
                      for (int i = 0; i < 1000000000; i++)
                          if (obj0 == null);
          
                      end = System.nanoTime();
                      difference = end - start;
                      differenceAvg +=difference;
                  }
          
                  System.out.println(differenceAvg/100);
                  differenceAvg = 0;
          
                  for (int j = 0; j < 100; j++)
                  {
                      start = System.nanoTime();
          
                      for (int i = 0; i < 1000000000; i++)
                          if (null == obj0);
          
                      end = System.nanoTime();
                      difference = end - start;
                      differenceAvg +=difference;
                  }
          
                  System.out.println(differenceAvg/100);
                  differenceAvg = 0;
          
                  for (int j = 0; j < 100; j++)
                  {
                      start = System.nanoTime();
          
                      for (int i = 0; i < 1000000000; i++)
                          if (obj1 == null);
          
                      end = System.nanoTime();
                      difference = end - start;
                      differenceAvg +=difference;
                  }
          
                  System.out.println(differenceAvg/100);
                  differenceAvg = 0;
          
                  for (int j = 0; j < 100; j++)
                  {
                      start = System.nanoTime();
          
                      for (int i = 0; i < 1000000000; i++)
                          if (null == obj1);
          
                      end = System.nanoTime();
                      difference = end - start;
                      differenceAvg +=difference;
                  }
          
                  System.out.println(differenceAvg/100);      
              }
          }
          

          在Object 初始化的情况下,什么都没有收集到;然而,当Object 是null 时,几乎在所有平均情况下,obj0 == null 都比null == obj0 快。我进行了 21 次额外的处决,其中 20 次是这种情况。

          【讨论】:

          • 这让我做了一些测试并在另一个thread 上发了一个帖子。我试图弄清楚当Object 被初始化而不是null 时比较快得多。
          • 你的结果并不完全不偏向于你编写代码的方式和你调用不同测试用例的顺序。我太仓促了,无法接受我认为可能但实际上并非如此的事情。
          猜你喜欢
          • 1970-01-01
          • 2014-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-22
          相关资源
          最近更新 更多