Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java String.intern()真的提高了性能吗?_Java_String_String Interning - Fatal编程技术网

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