gpt4 book ai didi

java - new String() 与文字字符串性能

转载 作者:太空狗 更新时间:2023-10-29 22:36:54 25 4
gpt4 key购买 nike

这个问题在 StackOverflow 上被问过很多次,但没有一个是基于性能的。

Effective Java 书中给出了这一点

If String s = new String("stringette"); occurs in a loop or in a frequently invoked method, millions of String instances can be created needlessly.

The improved version is simply the following: String s = "stringette"; This version uses a single String instance, rather than creating a new one each time it is executed.

因此,我尝试了这两种方法并发现性能显着改进:

for (int j = 0; j < 1000; j++) {
String s = new String("hello World");
}

大约需要 399 372 纳秒。

for (int j = 0; j < 1000; j++) {
String s = "hello World";
}

大约需要 23 000 纳秒。

为什么会有这么大的性能提升?内部是否发生了任何编译器优化

最佳答案

在第一种情况下,每次迭代都会创建一个新对象,在第二种情况下,它总是同一个对象,从字符串常量池中检索。

在 Java 中,当您这样做时:

String bla = new String("xpto");

您强制创建一个新的 String 对象,这会占用一些时间和内存。

另一方面,当您这样做时:

String muchMuchFaster = "xpto"; //String literal!

String 只会在第一次被创建(一个新对象),它会被缓存在 String 常量池中,所以每次你以它的字面形式引用它时,你得到完全相同的对象,速度快得惊人。

现在您可能会问...如果代码中的两个不同点检索到相同的文字并对其进行更改,那不是必然会发生问题吗?!

不,因为在 Java 中,您可能很清楚,字符串是不可变的!因此,任何会改变 String 的操作都会返回一个新的 String,让任何其他对同一文字的引用顺其自然。

这是不可变数据结构的优点之一,但这完全是另一个问题,我会就这个主题写几页。

编辑

澄清一下,常量池不是 String 类型独有的,您可以在此处阅读更多相关信息,或者如果您通过 google 搜索 Java 常量池。

http://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf

此外,您可以做一个小测试来说明这一点:

String a = new String("xpto");
String b = new String("xpto");
String c = "xpto";
String d = "xpto";

System.out.println(a == b);
System.out.println(a == c);
System.out.println(c == d);

有了这些,你大概可以算出这些 Sysouts 的结果:

false
false
true

因为 cd 是同一个对象,所以 == 比较成立。

关于java - new String() 与文字字符串性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14757978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com