1

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

我使用 Collection ( ArrayDeque) 来简单地按身份保存、添加、删除项目。我知道合同是供equals()在检查相等性时使用的集合,例如在 期间remove(obj),但在我的情况下,我想使用引用语义(如 IdentityHashMap 但不需要地图)。所以我很高兴知道我永远不会覆盖equals()集合中保存的任何对象(它被声明为保存一个接口)。

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

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

4

2 回答 2

0

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

于 2019-02-14T11:44:20.433 回答
0

制作该方法final不会避免虚拟调用,因为invokevirtual无论如何都会使用操作码,并且 JVM 无法判断该方法是否为最终方法。

好消息是,如果 JVM 看不到该方法在类路径中的任何位置被覆盖,那么 JVM 可能能够内联它或避免虚拟调用,因此您的性能会随着程序的运行而提高。

于 2019-02-14T11:07:52.560 回答