实现接口的开销

2022-09-03 03:12:24

我的一位同事告诉我,实现接口会带来开销。这是真的吗?

我不关心微优化;我只想知道这需要更深层次的细节。


答案 1

无法抗拒并测试它,它看起来几乎没有开销。

参与者是:

Interface IFoo    defining a method
class Foo: IFoo   implements IFoo
class Bar         implements the same method as Foo, but no interface involved

所以我定义了

Foo realfoo = new Foo();
IFoo ifoo = new Foo();
Bar bar =  new Bar();

并调用该方法,该方法执行 20 个字符串串联,每个变量执行 10,000,000 次。

realfoo:   723 Milliseconds
ifoo:      732 Milliseconds
bar:       728 Milliseconds

如果该方法不执行任何操作,则实际调用会更加突出。

  realfoo: 48 Milliseconds
  ifoo: 62 Milliseconds
  bar: 49 Milliseconds

答案 2

Java的角度来看,至少在最新版本的Hotspot中,答案通常是很少或没有开销

例如,假设您有如下方法:

public void doSomethingWith(CharSequence cs) {
  char ch = cs.charAt(0);
  ...
}

当然,CharSequence是一个接口。因此,您可能会期望该方法必须做额外的工作,检查对象类型,查找方法,并在doiing中搜索,因此可能最后搜索接口,等等 - 基本上您可以想象到的所有恐怖故事......

但实际上,VM可以比这更聪明。如果在实践中,您总是传递特定类型的对象,那么它不仅可以跳过objec类型检查,甚至可以内联该方法。例如,如果您在一系列字符串的循环中调用上述方法,Hotspot实际上可以将对charAt()的调用内联,以便从字面上获取字符成为几个MOV指令 - 换句话说,接口上的方法调用甚至可以变成根本没有方法调用。(附言此信息基于 1.6 更新 12 的调试版本的程序集输出。


推荐