以下内容取自 Best practice: Writing efficient code 但我不明白为什么
private static String x = "example";
比
快private static final String x ="example";
任何人都可以解释一下。
为字符串
使用静态变量定义静态字段时(也是 名为String的字段,类型为String, 你可以提高申请速度 使用静态变量(不是最终的) 而不是常数(最终)。该 对于原始数据则相反 类型,例如int。
例如,您可以创建一个String 对象如下:
private static final String x = "example";
对于这个静态常数(表示为 最后的关键词),每一次你 使用常量,一个临时String 实例已创建。编译器 消除“x”并替换它 字节码中的字符串“example”, 以便BlackBerry®Java®Virtual 机器执行哈希表查找 每次你引用“x”。
相比之下,对于静态变量(没有 最后的关键字),创建了String 一旦。 BlackBerry JVM执行 哈希表只查找它 初始化“x”,因此访问速度更快。
private static String x = "example";
你可以使用公共常量(即, 最后的字段),但你必须标记 变量为私有。
答案 0 :(得分:7)
我没有意识到这一点,但这对我来说很有意义:
JVM有一个内部String Literal Cache。每次使用文字创建一个String时,JVM都必须在缓存中查找它,如果不存在,则存储它。
现在编译器可以使用String文字内联最终变量,因为它在编译时是已知的,并且它似乎是性能的好主意。
所以你的代码:
static final String CONST = "myconst";
...
if (CONST.equals(aVar))
...
case CONST
...
由编译器重写为:
static final String CONST = "myconst";
...
if ("myconst".equals(aVar))
...
case "myconst"
...
如果JVM实现不够聪明,则需要在此示例中查找“myconst”三次。
如果不将CONST标记为“final”,则编译器无法“优化”它,因为变量可能会在运行时更改。您的代码将以1:1编译,JVM只需要在变量中查找Object。
btw:错误的JVM实现不应该定义您的编码风格。 “final”提供了很多安全性,所以只要它没有真正达到你的性能:不关心它是否增加或降低你的速度 - 无论如何它对于下一个JVM是不同的
答案 1 :(得分:2)
文字解释了它,只是阅读它。
但改写它: 它更快,因为它。 黑莓jvm的使用方式更好,使用非最终版本。 就像那样,因为它以那种方式设计
答案 2 :(得分:1)
这是Blackberry VM的细节。其他VM可能会采用不同的方式。
备注:在实际遇到性能问题(这称为“过早优化”)之前,不要过多关注优化,因为如果你这样做很可能会在你所在的地方泄漏性能永远不会指望它。
答案 3 :(得分:0)
有一个运行时String Literal Pool。当您将Strings创建为Final时,JVM每次使用时都会创建String的副本。当String是非final时,它会在你第一次创建它时被插入到String Literal Pool中,之后只是从池中查找它,这就避免了字符串的副本。