将变量定义为“本地”是否会使实现更快?

时间:2012-04-06 22:03:06

标签: java performance coding-style

编程时,我经常会遇到以下情况(在代码中描述)。我在块中定义了将要使用的变量。

    int maximumLengthOfToken = 0;

    while(fileScanner.hasNextLine())
    {
       String line; // definition
       line = fileScanner.nextLine();

       Scanner lineScanner; // definition
       lineScanner = new Scanner(line);

       String token = lineScanner.next(); // definition and assignment
       if(stringToMatch.endsWith(token))
        {
                 if(token.length() >= maximumLengthOfToken )
                  {
                     maximumLengthOfToken = token.length();  
                     builder.append(line);
                     builder.append("\n\n\n");
                  }
        }
    }
    fileScanner.close();

然而,有时候,为了“整洁”而且因为我来自C背景,我喜欢在顶部定义所有变量,无论它们在何处使用。所以我做了以下几点 -

    int maximumLengthOfToken = 0;
    String line; // definition
    Scanner lineScanner; // definition
    String token; // definition

    while(fileScanner.hasNextLine())
    {
       line = fileScanner.nextLine();
       lineScanner = new Scanner(line);

       token = lineScanner.next(); // definition

               if(stringToMatch.endsWith(token))
                {
                 if(token.length() >= maximumLengthOfToken )
                  {
                     maximumLengthOfToken = token.length();  
                     builder.append(line);
                     builder.append("\n\n\n");
                  }
        }
    }
    fileScanner.close();
“啊!它看起来很整洁”,我想。

但是,这对代码的性能有影响吗?第一种风格会导致更快的执行代码还是第二种风格?此外,在这种情况下的惯例是什么?我相信这是第一种风格。

6 个答案:

答案 0 :(得分:4)

没有。没有性能差异。

如果您对此表示怀疑,请问自己,“如果计算机距离2000字节,那么计算机需要更长时间才能查找变量,而不是200字节或20字节之外的计算机吗?”答案应该是否定的。

可能产生差异的唯一情况是,如果您的变量在使用之前从处理器缓存(see locality)中删除,在这种情况下,将变量移动到更靠近它的位置使用可能提高速度。但是,变量及其用途之间需要大量代码才能实现。

编译器也可能将您的方法编译为相同的字节码。简而言之,我认为你不必担心它。

答案 1 :(得分:2)

正如其他人所说,没有明显的性能差异。

您希望选择将变量声明放在方法的顶部,并将它们放在靠近它们的位置。不要强迫自己进入那个选择。你可以同时拥有两种方法 - 使你的方法非常短。当您发现自己面临这种选择时,请将其视为您的代码告诉您:“您的方法太长了。”

更短的方法更易于编写,更易于测试,更易于调试,更易于维护。如果你没有超过(例如)10行的方法,那么你将永远不会遇到这个问题 - 你将拥有更好的组织代码。

答案 2 :(得分:1)

这可能对代码的性能没有任何影响 - 我希望生成的字节码是相同的 - 但第一个版本通常被认为更易于维护和读取。

答案 3 :(得分:0)

在一般情况下,对于标准编译器链,可能存在轻微(或有时甚至是戏剧性的)差异,但对于Java很可能不会。

编译器可能会有所不同的地方是你所拥有的" varA"在一个范围内定义," varB"在不相交的范围内定义。编译器可能会观察到范围是不相交的,并为两者分配相同的堆栈槽,这非常,非常轻微地提高了解释器性能。但是,反过来说,这种技术可能会导致JITC更糟糕的优化,如果它不够聪明,无法弄清楚发生了什么。

答案 4 :(得分:0)

由于在现代Java实现中使用运行时优化,您不应该看到太多差异。因此,您应该主要关注清晰度和易维护性。

尽管如此,有一些很好的理由可以将变量声明为尽可能接近使用位置:

  • 更容易阅读,特别是对于非常短暂的(例如临时的)变量。读者可以立即看到变量的类型,而无需向上滚动到方法的开头。

  • 通过尽可能地限制变量的范围,可以减少无意识错误的可能性,例如重用循环计数器。

  • 当变量的范围有限时,某些优化(如转义分析)可能会表现得更好。

作为旁注,我使用C和Java进行编程,并且 偶尔难以从一个到另一个进行上下文切换。但是,在Java中使用C风格的约定(反之亦然)并不是一个好主意。 C约定由Java根本没有的限制决定 - 使用它们只会让你的代码更难以阅读。

答案 5 :(得分:0)

关于变量范围的最大“性能”差异将在垃圾收集中。在本地声明变量可能会允许GC更快地收集未使用的变量。