为什么String.equals()比自身更快? [英] Why is String.equals() faster than itself?

查看:94
本文介绍了为什么String.equals()比自身更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个更快版本的 String.equals()方法,只需复制即可开始。我发现的结果非常令人困惑。当我运行复制粘贴版本,定时并将其与JVM版本进行比较时,JVM版本更快。差异从6倍到34倍不等!简单地说,字符串越长,差异越大。

I was attempting to create a faster version of String.equals() method and started out by simply copying it. The result I found was quite confusing. When I ran the copy pasted version, timed it and compared it against the JVM one, the JVM version was faster. The difference ranged from 6x to 34x faster! Simply put, the longer the string, larger is the difference.

    boolean equals(final char a[], final char b[]) {
    int n = a.length;
    int i = 0;

    while (n-- != 0) {
        if (a[i] != b[i]) return false;
        i++;
    }
    return true;
}

public static void main() throws Exception {
    String a = "blah balh balh";
    String b = "blah balh balb";

    long me = 0, jvm = 0;

    Field value = String.class.getDeclaredField("value");
    value.setAccessible(true);

    final char lhs[] = (char[]) value.get(a);
    final char rhs[] = (char[]) value.get(b);
    for (int i = 0; i < 100; i++) {
        long t = System.nanoTime();
        equals(lhs, rhs);
        t = System.nanoTime() - t;
        me += t;
    }

    for (int i = 0; i < 100; i++) {
        long t = System.nanoTime();
        a.equals(b);
        t = System.nanoTime() - t;
        jvm += t;
    }

    System.out.println("me  = " + me);
    System.out.println("jvm = " + jvm);
}

输出:

me  = 258931
jvm = 14991

我写的equals()方法是在 String.equals()方法。为什么JVM版本比它的复制粘贴版本更快。是不是真的有效?

The equals() method I wrote is a copy-pasted version of the one found in String.equals() method. Why is the JVM version faster than it's copy-pasted version. Isn't it effectively the same?

有人可以解释为什么我看到这种明显的差异吗?

Could someone explain why I see such visible differences?

PS:如果你希望看到很大的差异,你可以创建长(真的,非常长)的字符串,最后只有一个字符不同。

PS: If you wish to see large differences, you could create long (really, really long) strings with just one character differing at the end.

推荐答案


为什么JVM版本比它的复制粘贴版本更快。是不是真的有效?

Why is the JVM version faster than it's copy-pasted version. Isn't it effectively the same?

令人惊讶的是,它不是。

Surprisingly, it isn't.

字符串比较是一种无处不在的操作,几乎可以肯定你的 JIT编译器 String.equals()的内在函数。这意味着编译器知道如何生成用于比较字符串的特制机器代码。当您使用 String.equals()时,这对程序员是透明的。

String comparison is such an ubiquitous operation that it is almost certainly the case that your JIT compiler has an intrinsic for String.equals(). This means that the compiler knows how to generate specially-crafted machine code for comparing strings. This is done transparently to you, the programmer, when you use String.equals().

这可以解释为什么 String.equals()比你的方法快得多,即使表面看起来相同也是如此。

This would explain why String.equals() is so much faster than your method, even if superficially they appear identical.

A快速搜索找到几个在HotSpot中提到这种内在的错误报告。例如, 7041100:在null检查之前执行的String.equals内部加载

A quick search finds several bug reports that mention such an intrinsic in HotSpot. For example, 7041100 : The load in String.equals intrinsic executed before null check.

可以找到相关的HotSpot源此处。有问题的函数是:

The relevant HotSpot source can be found here. The functions in question are:

  848 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {

  943 bool LibraryCallKit::inline_string_equals() {

这篇关于为什么String.equals()比自身更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆