来自 C/C++ 的人提出的基本性能问题。
我使用 Collection (ArrayDeque
) 来简单地按标识保存、添加、删除项目。我知道契约(Contract)规定集合在检查相等性时使用 equals()
,例如在 remove(obj)
期间,但就我而言,我想使用引用语义(如 IdentityHashMap 但不需要映射)。因此,我很高兴知道我永远不会覆盖集合中保存的任何对象(声明为保存接口(interface))上的 equals() 。
来自 native 编程,我无法避免问自己,remove(obj)
的编译代码是否会遍历项目并对 Object.equals()
执行虚拟调用,只是为了最终比较地址?由于我正在存储接口(interface)引用,所以没有办法(?)使用 final
来优化它,因此编译器不会费心进行无用的调用(即内联它们) - 但现在我有点超前了,因为无论如何这样的优化可能是不必要的,并且 JVM 有其他方法(去虚拟化?)在这种情况下生成最佳代码。
假设我的代码需要通过首先考虑这个方面来获得的优化级别 - 我的理解正确吗?对于这种情况,什么是好的设计?
最佳答案
使方法成为final
不会避免虚拟调用,因为invokevirtual
操作码无论如何都会被使用,并且JVM无法判断该方法是否是final。
好消息是,如果 JVM 无法看到该方法在类路径中的任何位置被重写,那么它可能能够内联它或避免虚拟调用,这样您的性能就会随着程序的运行而提高。
关于比较项目时的 Java 集合性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54688783/