• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

为什么不直接比较 e.key 而不是其分配把变量?

用户头像
it1352
帮助8

问题说明

在阅读HashMap的源代码时,我在public V put(K key, V value)中看到了这个片段:

While reading the source code for HashMap, I came across this snippet in public V put(K key, V value):

for (Entry<K,V> e = table[i]; e != null; e = e.next) {
    Object k;
    if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
        V oldValue = e.value;
        e.value = value;
        e.recordAccess(this);
        return oldValue;
    }
}

为什么要将 e.key 分配给 k 进行比较?为什么不直接比较,比如:

Why assign e.key to k for comparing? Why not compare directly, like:

if (e.hash == hash && (e.key == key || key.equals(e.key))

-------- 更新 ------------

------------------- UPDATE ------------------------

根据@seand的回答,我做了更详细的调查:

According to the answer from @seand, I do more detail investigation:

import com.test.Test;

    public class Main {
        public static void main(String[] args) {
            Test t = new Test();
            int a = t.a;
            int b = a;
        }
    }

类 Test 有一个 int 字段;

class Test has a int filed a;

使用 javap -c Main 获取类文件内容:

Using javap -c Main to get the class file content:

  public static void main(java.lang.String[]);
Code:
   0: new           #2                  // class test/Test
   3: dup           
   4: invokespecial #3                  // Method test/Test."<init>":()V
   7: astore_1      
   8: aload_1       
   9: getfield      #4                  // Field test/Test.a:I
  12: istore_2      
  13: iload_2       
  14: istore_3      
  15: return    

int a = t.a 表示

8:[load the t object]
9:[access the field a]
12:[store the value to a]

参考jvm规范获取[getfield的信息]

Refer to jvm specification get information of [getfield]

int b = a 表示:

13:[load the local variable]
14:[store the value to b];

访问局部变量似乎比访问类字段更合理.

It seems reasonable to access the local variable than the class field.

正确答案

#1

我猜这是一种优化,可以节省对 e.key 的额外查找.(虽然它实际上不是使用invokevirtual 的方法调用,但它可以节省一定程度的间接性).由于这是一个使用非常频繁的库函数,作者可能会使用他们能想到的所有技巧来获得最大性能.您还可以看到它如何在 k = e.key 中检查对象身份,这可以避免成本稍高的 equals() 调用.

My guess is it's an optimization which saves an extra lookup to e.key. (Though it's not actually a method call that's using invokevirtual, it may save a level of indirection). Since this is a very heavily used library function the authors likely used every trick they could think of for maximum performance. You can also see how it checks for object identity in k = e.key which may avoid a slightly more costly equals() call.

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tangicbec
系列文章
更多 icon
同类精品
更多 icon
继续加载