与equals相比,如何使用==运算符带来性能提升? [英] How use of == operator brings in performance improvements compared to equals?

查看:245
本文介绍了与equals相比,如何使用==运算符带来性能提升?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Joshua Bloch的有效JAVA中,当我读到静态工厂方法时,有一个声明如下

In Effective JAVA by Joshua Bloch, when I was reading about static factory methods , there was a statement as follows


静态工厂方法从
返回相同的对象重复调用允许类保持严格控制
随时存在的实例。执行此操作的类被称为
实例控制。编写
实例控制类有几个原因。实例控制允许类
保证它是单例(第3项)或不可实例化(第4项)。
此外,它允许不可变类(第15项)作出保证
,表示不存在两个相等的实例:a.equals(b)当且仅当a == b时。如果
类产生了这种保证,那么它的客户可以使用==
运算符而不是equals(Object)方法,这可能会导致
的性能提升。枚举类型(第30项)提供此保证。

The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its cli- ents can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.

为了研究==运算符如何带来性能改进,
我得到了查看 String.java

To investigate how == operator brings in performance improvements , I got to look at String.java

我看到了这个片段

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

通过性能提升,他的意思是什么?它如何带来性能提升。

By performance improvement what does he mean here ? how it brings performance improvement .

他是否要说以下

如果每个班级都可以确保a.equals(b)当且仅当a == b时,这意味着它带来间接要求,即不能有对象引用2个不同的存储空间并且仍然保持相同的数据,即存储器浪费。如果他们拥有相同的数据,那么他们就是同一个对象。那就是他们指向相同的内存位置。

我对这个推断是否正确?

Am I right in this inference ?

如果我错了你可以指导我理解这个吗?

If I am wrong can you guide me in understanding this ?

推荐答案

引用部分的含义是不可变类可以选择 实习生 它的实例。这很容易通过Guava的 Interner ,例如:

What the quoted portion means is that an immutable class can choose to intern its instances. This is easy to implement via Guava's Interner, for example:

public class MyImmutableClass {
    private static final Interner<MyImmutableClass> INTERN_POOL = Interners.newWeakInterner();
    private final String foo;
    private final int bar;

    private MyImmutableClass(String foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public static MyImmutableClass of(String foo, int bar) {
        return INTERN_POOL.intern(new MyImmutableClass(foo, bar));
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(foo, bar);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;        // fast path for interned instances
        if (o instanceof MyImmutableClass) {
            MyImmutableClass rhs = (MyImmutableClass) o;
            return Objects.equal(foo, rhs.foo)
                    && bar == rhs.bar;
        }
        return false;
    }
}

这里,构造函数是私有的:所有实例都有通过 MyImmutableClass.of()工厂方法,它使用 Interner 来确保新实例是 equals()到现有实例,而是返回现有实例。

Here, the constructor is made private: all instances have to be through the MyImmutableClass.of() factory method, which uses the Interner to ensure that if the new instance is equals() to an existing instance, the existing instance is returned instead.

实习只能 用于不可变对象,我指的是可观察状态的对象(即所有外部可访问方法的行为,特别是等于() hashCode())对象的生命周期不会改变。如果你是实习可变对象,修改实例时行为就会出错。

Interning can only be used for immutable objects, by which I mean objects whose observable state (i.e., the behaviour of all its externally-accessible methods, in particular equals() and hashCode()) does not change for the objects' lifetimes. If you intern mutable objects, the behaviour will be wrong when an instance is modified.

正如许多其他人已经说过的那样,你应该仔细选择哪些对象实习,甚至如果他们是不可改变的只有当实习值的集合相对于您可能具有的重复数量较小时才这样做。例如,通常不值得实习 Integer ,因为有超过40亿个可能的值。但值得实习最常用的 Integer 值,实际上, Integer.valueOf()实习值在-128和127之间。另一方面,枚举很适合实习生(根据定义他们是实习生),因为可能的价值观很小。

As many other people have already stated, you should carefully choose which objects to intern, even if they're immutable. Only do it if the set of interned values is small relative to the number of duplicates you are likely to have. For example, it's not worth interning Integer generally, because there are over 4 billion possible values. But it is worth interning the most commonly-used Integer values, and in fact, Integer.valueOf() interns values between -128 and 127. On the other hand, enums are great to intern (and they are interned, by definition) because the set of possible values is small.

一般来说,大多数类都需要进行堆分析,例如使用 jhat (或者,插入我自己的项目, fasthat ),以确定是否有足够的重复以保证实习。在其他情况下,只是保持简单,不要实习。

For most classes in general, you'd have to do heap analysis, such as by using jhat (or, to plug my own project, fasthat), to decide if there are enough duplicates to warrant interning. In other cases, just keep it simple and don't intern.

这篇关于与equals相比,如何使用==运算符带来性能提升?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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