当前位置: 首页 > 面试题库 >

传递接口与重载类之间的性能差异

羊舌承天
2023-03-14
问题内容

有一个共识,使用接口比使用类更好。我当然同意:库法接受ArrayList替代的List将是一个废话。

也有一个共识,就是性能总是一样的。在这里,我的基准要求不同。 接口和抽象类结果都有1到4种实现。当使用两个以上的实现时,性能开始出现差异。我正在寻找这种行为的解释(以及错误共识的由来)。


问题答案:

有一个共识,使用接口比使用类更好。

这太简单了。接口和抽象类都
具有彼此之间的优势。

链接到的答案建议将变量声明为java.util.List,而
不是尽可能声明为java.util.ArrayList 。没错,使用List可以为
您提供更大的灵活性,以便以后选择其他实现类,
因此,当您不需要特定于ArrayList的方法
(例如.trimToCapacity())时,这是一件好事。但是,此建议通常与
接口或类无关,并且如果
java.util.List是抽象类也是如此。

也有一个共识,就是性能总是一样的。

流行的建议是,不要担心
类和接口之间的性能差异,而应该根据良好的
编程原理在它们之间进行选择。这是防止程序员
担心无关紧要的性能差异的好建议。但是有时会
误解为暗示没有区别,这是不正确的。这里
是一个小的差异:类是更快的。

通过类的方法调用,在类中的固定偏移量处有一个
vtable
,并且
在该表内的已知偏移量处找到了所需方法实现的指针,因此跳转到目标非常简单。
但是,尽管一个类只能扩展一个超类,但是一个类可以实现
任意数量的接口,因此通过接口进行方法调用更加
复杂。对于接口调用,它必须先查找类的
接口列表以找到所需的接口,然后才能
在该接口的表中查找方法实现。

当使用两个以上的实现时,性能开始出现
差异。

无论使用类还是使用接口,多态调用都会
在CPU上引起流水线刷新,因为CPU无法提前看到跳转的目标,因此
成本很高。如果在运行时知道调用站点是同
构的(oligo表示“很少”),则性能会急剧提高,因为
好的JVM会专门处理这些情况。对于单态情况,JVM可以
直接跳转到单个目标方法,甚至可以内联。对于
二态情况下,实现了o.f();仿佛(无效语法): if (o.getClass() == A.class) A::f(o) else B::f(o);。

实际上,我不确定为什么在
基准测试中双态情况和单态情况一样快– CPU的分支预测器
难道不会在随机数据上有一半的时间出错吗?也许那里还有其他细微之处



 类似资料:
  • 问题内容: 我正在运行以下代码,但有时在运行时会出现某种并发异常。 我对其进行了重构以解决并发问题,但这确实使我提出了一个问题。如果将for构造更改为Iterator模式,性能会有所不同吗?foreach构造和Iterator类之间的访问级别有什么区别? 问题答案: 区别主要在于语法糖,不同之处在于可以从迭代中删除项目。从技术上讲,增强的循环使您可以循环遍历所有,其中至少包括s和数组。 不必担心性

  • 上次,我发现了Java8及以上版本函数式编程的难点,并在Collectors类中发现了一个静态方法。 我们有一个类员工像: 假设我们有一个类的POJO列表,并且我们希望接收一个所有员工姓名的列表。我们有两种方法,比如: 我知道第一种方法在上使用终端操作,而第二种方法在上使用中间操作,但我想知道第一种方法的性能是否比第二种方法差,反之亦然。如果您能解释第一种情况的潜在性能下降,当我们的数据源(emp

  • 是的,这是一个老话题,但我仍然有一些困惑。 在Java,人们说: > 如果我随机访问它的元素,ArrayList比LinkedList快。我认为随机存取意味着“给我第n个元素”。为什么ArrayList更快? LinkedList的删除速度比ArrayList快。我理解这一点。ArrayList速度较慢,因为需要重新分配内部备份阵列。代码说明: LinkedList的插入速度比ArrayList快

  • 问题内容: 我正在计算稀疏自动编码器的算法。我已经使用和在python中实现了它。代码几乎相同,但是性能却大不相同。matlab完成任务所需的时间为0.252454秒,而numpy为0.973672151566,几乎是原来的四倍。在最小化问题中,我将在以后多次调用此代码,因此这种差异会导致实现之间的延迟几分钟。这是正常行为吗?如何提高numpy的性能? numpy实现: Sparse.rho是调整

  • 是的,这是一个老话题,但我还是有些困惑。 在爪哇,人们说: LinkedList的插入速度比ArrayList快。这里插入是什么意思?如果这意味着向后移动一些元素,然后将元素放在中间的空点,那么ArrayList应该比LinkedList慢。如果插入只意味着添加(对象)操作,这怎么会慢呢?