为什么 String.equals() 比它本身快?

2024-03-25

我试图创建一个更快的版本字符串.equals() http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#equals%28java.lang.Object%29方法并从简单地复制开始。我发现的结果非常令人困惑。当我运行复制粘贴版本、计时并将其与 JVM 版本进行比较时,JVM 版本更快。速度差异从 6 倍到 34 倍不等!简单来说,字符串越长,差异越大。

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);
}

Output:

me  = 258931
jvm = 14991

我编写的 equals() 方法是中找到的方法的复制粘贴版本字符串.equals() http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#equals%28java.lang.Object%29方法。为什么 JVM 版本比复制粘贴版本更快?效果上不是一样吗?

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

PS:如果您希望看到较大的差异,您可以创建很长(非常非常长)的字符串,并且末尾只有一个字符不同。


为什么 JVM 版本比复制粘贴版本更快。效果上不是一样吗?

令人惊讶的是,事实并非如此。

字符串比较是一种普遍存在的操作,几乎可以肯定,您的即时编译器 http://en.wikipedia.org/wiki/Just-in-time_compilation有一个内在的String.equals()。这意味着编译器知道如何生成特制的机器代码来比较字符串。当您使用时,这对程序员来说是透明地完成的String.equals().

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

快速搜索发现几个错误报告提到了 HotSpot 中的此类内在函数。例如,7041100:在空检查之前执行的 String.equals 内在函数中的加载 https://bugs.java.com/bugdatabase/view_bug?bug_id=7041100.

相关HotSpot源码可以找到here http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/file/e6d7eed3330c/src/share/vm/opto/library_call.cpp。有问题的函数是:

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

and

  943 bool LibraryCallKit::inline_string_equals() {
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 String.equals() 比它本身快? 的相关文章

随机推荐

  • 如何限制对 Firestore 中用户拥有的文档的写入?

    我有一些文章 每篇文章都有一个参考字段到个人资料document撰写该特定文章的作者的姓名 经过身份验证的用户 使用 Firebase 的身份验证 将与这些配置文件关联 仅当当前登录的用户拥有该文章时 如何才能使这些文章可由该用户编辑 在
  • 构造函数中具有实例名称知识的 Matlab 类

    我想要一个类 在其构造函数中可以了解其实例名称 提取为字符串 目前 我像这样提取名称 classdef mysession methods Access public function this mysession varargin thi
  • 在 Rails 5+ 中禁用 sprocket 资源缓存

    我已经尝试了很多禁用 Rails 中的 sprocket 资源缓存 但没有成功 我尝试配置development rb 但它根本不起作用 我正在使用此代码来禁用缓存生成 config assets cache store null stor
  • 更改最后一个
  • 的 CSS
  • 我想知道是否有某种方法可以更改最后一个 CSS 属性li在使用 CSS 的列表中 我已经研究过使用 last child 但这看起来确实有问题 我无法让它为我工作 如有必要 我将使用 JavaScript 来完成此操作 但我想知道是否有人可
  • 如何解释 Seaborn distplot 的轴

    Snippet plt figure figsize 10 5 plt xticks np arange 0 11 1 sns distplot 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 kde F
  • 如何增加LVL缓存有效时间?

    我已经在我的应用程序中实施了 LVL 服务器托管策略 我知道lvl服务器响应会在设备中缓存一段时间 因此用户可以在没有互联网连接的情况下使用应用程序 然后lvl使用缓存的许可证 我想知道这个期限到底有多长以及如何延长它 基本上 lvl 我已
  • 用于在不同工作簿中选择范围的 VBA 对话框

    我想允许用户选择可能位于不同工作簿中的范围 我尝试使用 inputbox type 8 来执行此操作 它可以选择工作簿中的数据 但不允许我在不同的工作簿中选择范围 因此我想要一个允许我执行此任务的对话框 由于我有空 我为您创建了一个示例 创
  • .JSchException:数据包损坏

    我在 RHEl 6 上使用 Jsch 0 1 51 和 Jdk 1 7 51 在与远程计算机进行会话时 我收到以下异常 com jcraft jsch JSchException Packet corrupt at com jcraft j
  • Python venv env 失败 - [WinError 2] 系统找不到指定的文件

    我在 Windows 10 计算机上安装了最新版本的 Python 3 8 2 我以前有Python 3 7 我将其卸载并确认在系统路径中不再引用它 安装最新版本后 我以管理员身份运行CMD py m venv env 我收到此错误 错误
  • 添加到Python中正在迭代的双端队列?

    我在 Python 中有一个双端队列 正在对其进行迭代 有时 当我进行交互时 双端队列会发生变化 从而产生RuntimeError deque mutated during iteration 如果这是一个 Python 列表而不是双端队列
  • 如何部署Tomcat的示例websocket应用程序?

    我正在尝试了解如何部署 Apache Tomcat 7 中引用的示例WebSocket 操作方法 http tomcat apache org tomcat 7 0 doc web socket howto html page 应用程序开发
  • 根据室外温度设置背景颜色

    嘿哦 所以 我有一个温度小部件要在我正在进行的项目上实现 没有什么特别困难的 我有一个免费的 API 来检索我需要的数据等 但是 和我一起工作的可爱设计师有一个颜色特征 我对此一无所知 他会根据当前的天气温度来定义背景颜色 我的意思是如果温
  • 在 ReactJS 中禁用 ContextMenu

    第一篇文章在这里 所以希望我能以最有帮助的方式提出这个问题 我对编码还很陌生 在努力推动自己的过程中 我决定尝试使用 React 来重新创建扫雷 而不是使用任何教程 我已经获得了很多功能 但我真的停留在这部分上 我正在使用事件侦听器 onC
  • 如何快速本地化故事板?

    我正在尝试使用 Swift 3 和 Xcode 8 1 本地化我的应用程序 我正在尝试使用 Storyboard main strings German 并以编程方式使用来本地化应用程序 NSLocalizedString 我能够使用编程方
  • 如何从多个网站获取 RSS 源

    我正在为我的网站获取 RssFeeds 并且它正在显示 但是如何从多个站点获取 RSS Feed 并且需要从第一个站点的三个 feed 第二个站点的三个 feed 等依次显示 主要来自 CNN BBC 这是我的代码 protected vo
  • 如何使用 asp.net 和 C# 强制回发

    我与客户安排了一个演示 现在我需要一个快速而肮脏的修复 明天我会找到更合适的解决方案 但目前我需要一种方法来强制回发或刷新页面 我试过 Response Redirect 但它带我到一个页面 上面写着 对象已移至此处 这里 是一个超链接 可
  • Cabal - 在构建库时公开所有模块

    是否可以告诉Cabal在构建库时公开所有模块 现在我必须提供很长的模块列表exposed modulescabal 配置文件部分 您必须列出 cabal 配置文件中的所有模块 在你的情况下 你只需将模块列表放在后面exposed modul
  • 将列表设置为 pandas 数据帧的列中的值

    假设我有一个数据框df我想创建一个填充 0 的新列 我使用 df new col 0 到目前为止 没有问题 但如果我想使用的值是一个列表 它就不起作用 df new col my list ValueError Length of valu
  • jQuery 在选择框上设置选项

    我似乎无法让这个工作
  • 为什么 String.equals() 比它本身快?

    我试图创建一个更快的版本字符串 equals http docs oracle com javase 7 docs api java lang String html equals 28java lang Object 29方法并从简单地复