2009-07-22 146 views
5

equals()方法(并且就此而言也是compareTo()方法)可以成为性能热点(例如,在高流量的HashMap中)。我想知道当这些案例证明有必要时,人们采用哪些技巧来优化这些方法。优化equals()方法

IntelliJ IDEA的,例如,生成以下内容:

public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    ... 
} 

你遇到那还有什么可以写一个很好的执行equals()方法的指导方针?

回答

14

一些一般性的想法,不一定具体到equals()

  • 失败尽早。与您发布的代码段类似,请先从最广泛的排除条件开始,然后变得更加细化,以便该方法可以尽快返回。
  • 仅比较平等要求的属性。我有时看到人们比较每个类提供的信息,尽管只有少数属性实际上对两个类实例的平等起到了语义作用。这当然高度依赖于你的课程和设计
  • 如果可能的话,避免平等递归。根据什么样的阶级属性,你比较,你可能会进入自己的情况,你是递归调用自己或其他物体equals(),它可以有一个隐藏的性能影响

除了性能方面的考虑,不要”忘记了equals API contract以确保您的平等是自反对称传递一致,并始终覆盖hashcode()还有,当你重写equals()

5

我想你,因为你说已经是到它的一个重要组成部分:

...当他们证明是必要的。

记住优化的一般规则:

  1. 不要
  2. 不要...但
  3. 优化

我听说他们以前个人资料几年前的一个班级,尽可能接近我可以告诉C2是来源。

2

查看书籍Joslas Bloch的“Effective Java”。它有一些惊人的提示和关于这个问题的整个部分。祝你好运!

1

您可能会从string interning得到提示。

如果您的对象是不可变的,您可以通过使用静态工厂方法并将唯一实例填充到散列表中来实现自己的“实习”。如果你这样做,那么当引用相等时,对象是相等的。

+0

我应该提到工厂方法会在用等价值调用哈希表时抛出相同的实例。 – devgeezer 2009-07-22 01:57:50

+1

你需要小心'实习'。如果做错了,它可能导致性能问题和存储泄漏。实际上,这就是为什么调用String.intern()可能是个坏主意。 – 2009-07-22 03:08:38

+0

这些都是值得注意的事项。我想我的优化建议通常是看看其他地方,除非你有充分的证据表明Equals(...)正在采取无法接受的长时间。 – devgeezer 2009-07-22 03:46:40

1

如果您的对象处于您完全控制所调用equals()的环境中,那么您应该跟踪正在执行的比较类型,并适当调整equals()方法。

你也许能够证实某些情况下不会发生,所以不需要内equals()进行编码,如:

  • 比较null
  • 比较不同类型
  • 比较自我

您还可以决定您执行检查的适当顺序,检查最常见的失败原因fir ST。

0

我建议让HashMap变大一点是equals()是很贵的(例如通过减少负载因子)。这样你会减少碰撞,并希望如果(o ==这个)返回true将最经常匹配。