比较项目时的Java收集性能

时间:2019-02-14 10:57:09

标签: java performance collections equals identity

来自C / C ++的人的基本性能问题。

我正在使用一个收藏夹(ArrayDeque)来按标识简单地保存,添加或删除物品。我知道合同是集合在检查相等性时使用的equals(),例如在remove(obj)期间,但是在我的情况下,我想使用引用语义(例如IdentityHashMap,但不需要映射)。因此,只需知道就可以了,我永远不会覆盖集合中所声明的任何持有对象的equals()(声明为持有接口)。

来自本机编程,我无法避免地问自己,remove(obj)的编译代码将遍历项目并在Object.equals()上执行虚拟调用只是最终比较地址?由于我存储的是接口引用,因此没有方法(?)使用final对此进行优化,因此编译器不会打扰无用的调用(即内联它们)-但现在,我已经超越了自己因为无论如何都可能不需要这种优化,并且在这种情况下JVM还有其他方法(去虚拟化?)来生成最佳代码。

假设我的代码需要首先通过考虑此方面而获得的优化级别-我的理解正确吗?这种情况下有什么好的设计

2 个答案:

答案 0 :(得分:0)

使方法final无法避免虚拟调用,因为无论如何都将使用invokevirtual操作码,并且JVM无法确定方法是否为最终方法。

好消息是,如果JVM无法看到方法在类路径中的任何地方都被覆盖,则JVM可以内联它或避免虚拟调用,因此您的性能将随着程序的运行而提高。

答案 1 :(得分:0)

使用remove方法时,它将调用equals方法进行比较。理想情况下,您应该重写equals和hashcode方法以使用此类方法。否则,默认情况下会进行类型检查和地址比较。强烈建议在使用Collections方法时定义equals和hashcode方法的实现。 关于性能,是的,您是对的-集合中的所有对象将被线性扫描,直到J​​VM遇到正确的匹配为止。这是线性搜索,因此此删除操作的时间复杂度为O(n)。