Java String.intern()真的提高了性能吗?
我做了一些调查,以了解Java String.intern()真的提高了性能吗?,java,string,string-interning,Java,String,String Interning,我做了一些调查,以了解String.intern()方法是如何在java中实现的 我从开放的JDK 6中查看了实习生池的C++实现,在那里我看到了一个简单的哈什特集< /C>。对我来说,这意味着当有人试图实习一个字符串时,接下来的步骤应该完成: 查找与给定字符串关联的哈希代码 寻找合适的桶 将给定字符串与桶中的所有其他字符串进行比较。 在此步骤之前,可能有0个字符串、一个字符串或许多字符串 桶里的绳子。因此,如果给定的字符串之前已 放入桶中,我们将得到至少一个比较(即 最好的情况。当然可能有很多
String.intern()
方法是如何在java中实现的
我从开放的JDK 6中查看了实习生池的C++实现,在那里我看到了一个简单的<代码>哈什特集< /C>。对我来说,这意味着当有人试图实习一个字符串时,接下来的步骤应该完成:
查找与给定字符串关联的哈希代码
寻找合适的桶
将给定字符串与桶中的所有其他字符串进行比较。
在此步骤之前,可能有0个字符串、一个字符串或许多字符串
桶里的绳子。因此,如果给定的字符串之前已
放入桶中,我们将得到至少一个比较(即
最好的情况。当然可能有很多碰撞和碰撞
现在,桶中还有许多其他字符串)
如果已在桶中找到该字符串,则应将其删除
由intern()
方法返回
如果在桶中未找到字符串,则应将其放入桶中
在bucket中,并通过intern()
方法返回
很多人说str1.intern()==str2.intern()
比str1.equals(str2)快
但我看不出为什么它应该更快
正如我在str1.equals(str2)
中看到的,在String.equals()方法中,我们总是有两个字符串逐字符比较
在str1.intern()==str2.intern()
的情况下,我们需要从池中获取或放置字符串多少次比较(对,这可能是大量比较,它们也是简单的逐字符比较)
因此,在str1.intern()==str2.intern()
的情况下,即使我们使用=
来比较字符串,我们也会有许多额外的操作,比如前面描述的比较
当我理解它时,我决定做一些基准测试
第一个结果告诉我str1.intern()==str2.intern()
比str1.equals(str2)
快
这种行为是由于String.intern()
方法是本机方法,因此不应该每次都解释它,而String.equals()
是一种java方法
因此,我决定使用-Xcomp
选项让JVM在启动时编译所有代码
在那之后,equals展示了比实习生更好的速度
我在Java6和Java7上测试了它
所以我的问题是,你有没有见过这样一种情况:实习时字符串比较的速度提高了?是的,怎么可能
或者可能intern()
只能帮助节省更多的可用内存?String.intern()
意味着减少内存的使用
只有当内存中有许多相同字符串的多个副本时,才使用插入字符串(如果有)。通过插入字符串,所有这些副本将使用相同的引用
我只看到当我有数百万个相同字符串的副本时,实习字符串是有用的
与任何类型的优化一样,只有在出现性能或内存问题并且您已经对其进行了分析,从而检测到这是瓶颈之后,才能进行优化
有关字符串内部处理的更多详细信息。关于为什么str1.intern()==str2.intern()
可能更快的问题:
这是String.equals()
实现-正如您所看到的,根据比较的字符串,它可能非常低效
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
您的步骤可能要快得多:1) hashCode()对任何字符串计算一次,因为它是不可变的,并且速度相当快
2) 查找存储桶为O(1)
3) 将您的字符串与同一存储桶中的其他字符串进行比较-可能有一些字符串,但速度仍应快于
equals()
4) 5)速度快
不要忘记,对任何字符串只需执行一次上述操作,一旦执行了
intern()
ed,则从第一次比较返回结果。str1.intern()==str2.intern()
-否!你应该已经把琴弦锁好了。在比较站点实习他们纯粹是开销。(当你正确地使用它时,实习是否有用仍然是有争议的,但这样的实习是无用的。)我不认为这完全回答了这个问题,我手头也没有参考资料,但我记得很久以前读到过一篇文章,String.hashCode
方法已经为非常好的分发进行了优化,这样,在哈希表中,您将得到很少的冲突。“人们说”永远不是做任何事情的好理由+1用于做你自己的研究。+1用于实际测试,以回答“X比Y快吗”的问题。+1很好的研究,也是一个有趣的问题!例如,我曾经查看过生产服务器中经常出现堆空间问题的堆转储。我发现8MB的字符串包含值“0”和“1”。这是一个使用intern
@Brandon的好机会,这听起来更像是数据类型的错误选择。在这种情况下,当需要字符串表示时使用String.valueOf
不是更好的选择吗?同意-回顾源代码,我找不到我在那个例子中使用intern
的地方,但我看到了一堆boolean.valueOf
,Integer.valueOf
,这是一个更好的选择,等等。我想我最后实习的是房产名称。“0”和“1”等是从数据库加载的属性值,有一小部分固定的属性经常加载不同的值。“不要忘记,任何字符串只需执行一次上述操作,一旦插入,第一次比较就会返回结果。”我可能遗漏了什么,假设我们有str1.intern(),然后又有str1.intern()。我以为第一行会把绳子放到游泳池里(使所有的步骤)a