2011-07-26 32 views
3

我已经读过,做一些最终的东西,然后在循环中使用它会带来更好的性能,但它对一切都有好处吗?我有很多地方没有一个循环,但我添加最后的局部变量。它会让它变慢还是变好?总是使用Final?

还有一些地方我有一个全局变量final(例如android paint),这是否意味着我不必在循环中使用它作为本地最终?

回答

6

你应该考虑的第一件事是;什么是我可以写这个代码的最简单最清晰的方式。通常这表现良好。

final局部变量不太可能影响性能。当你有很长的方法时,它们可以帮助清晰,但我建议分手方法是一种更好的方法。

final领域可能会影响性能,以小的程度,但一个更好的理由,使其final是要清楚,这个领域从未改变(这也有助于JIT)

+0

我想补充一点,final字段与local字段的final字段非常不同。为了在并发编程中实现程序的正确性,进行字段最终决定通常是绝对必要的。 –

+0

除了传递一个新对象到另一个线程的相当微妙的条件(我没有看到这个失败的例子),如果一个字段可能是“最终”但不是,它将表现相同。使它成为'final'清楚地表明,原语或引用不会存在线程安全问题,因为它不能被改变。注意:引用的对象仍然可以更改。 –

+0

我只是留下规范的链接。最终变量:http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4最终字段:http://java.sun.com/docs/books/jls/third_edition /html/memory.html#66562 tl; dr:前者对文档很有用,后者可以以明显的方式改变程序的行为。 –

0

理论上讲,如果你制作一个局部变量fi​​nal,它可以被优化。我不认为让他们成为最终的你自己真的会提高性能,因为优化器可能已经检测到你的本地人不会改变。也就是说,它可以帮助一点点伤害。

在某些情况下,它有助于将一个变量变为两个,例如,从这个

String a = "foo"; 
if (lol) a += "bar"; 

for(.. 1000 ...) doSomething(a); 

final String a; 
{ 
    String ma = "foo"; 
    if (lol) ma += "bar"; 
    a = ma; 
} 

for(.. 1000 ...) doSomething(a); 

免责声明:我不是一个JIT专家。

3

从我的经验,多数变量可以声明final

但是,它看起来非常丑陋。这是我反对的主要观点。

如果程序的部分不是性能关键,请注意过早优化。

2

这里是我的2美分:

使用最后的属性,以尽量减少可变性和文档的目的,只有当他们在内部/匿名类中使用的最终使用局部变量。

不要使用它进行微优化!特别是不要在类或方法中使用它们,因为您认为它会提高性能。使类和方法最终到禁止继承或重写方法。

2

在可能的情况下(对于字段和变量,而不是类和方法)使用final是一种很好的形式,如果没有其他原因而使测试更容易。决赛永远不会对表现产生负面影响。

0

最终变量是常量,因此编译器可以生成常量值而不是变量引用指令。当然,这会提高速度(并且通常也是大小)。

也有一些地方,我有一个全局变量最后(例如,android paint),这是否意味着我不必在循环中使用它作为本地最终?

对不起,你的意思是,你不必:

final int somefinalvalue = 0; 

void amethod() { 
    final int somefinalvalue = 0; // repeated from global one 
} 

还是什么?请记住,如果您声明与全局名称相同的局部变量,那将会“影响”全局变量。即它实际上是一个完全不同的变量。如果你已经拥有全球性的,那么就使用它。无需重新申报。

+0

我认为他意味着当地的“缓存”领域。 –

+0

在Java中,它们是*不变的*,但不是*常量*,就好像编译器知道它将具有什么值。编译器只是禁止分配。 – marc

+0

@Marc这就是为什么我说编译器“可以”,而不是“会”。如果编译器足够聪明,通过一些分析可以决定是否将其优化为常量(对于简单的值,例如整数或浮点)。 – LeleDumbo

3

不要考虑性能。对象成员(字段)上的final具有显着的内存语义,可以提高性能(但更重要的是,它通常有必要使代码正常工作)。您应该始终将final放在对象成员上。但对于局部变量,只有在维护人员接触到代码时,才能改善代码的可重用性,或者防止出现错误。

Java社区的普遍共识是,每个本地变量的final都会使代码难以阅读。在性能方面,由于易于为编译器分析本地变量,因此可以预期不会进行优化。换句话说,编译器可以自己计算出来。

1

属性的最终不应该对性能产生任何影响。除了:在一个多线程环境中,有多个线程访问相同的字段,“不知道”是否必须重新发布。局部变量的最终结果完全没有影响,因为除了本地范围无论如何都可以访问局部变量。在JIT编译期间,最终的方法可能会产生影响。如果一个方法是final和small,编译器可以将它内联到循环中,因为很明显没有人会覆盖它。 我通常根本不使用最终的属性,因为最终的属性不能从数据库轻松加载等等。声明参数方法最终lokos丑(我从来没有分配给他们在我的代码里面),但可能会阻止简单的错误来自typoes。但是,如果您开始使用适当的名称作为变量,则会发出此类错误。

相关问题