实现接口的开销
2022-09-03 03:12:24
我的一位同事告诉我,实现接口会带来开销。这是真的吗?
我不关心微优化;我只想知道这需要更深层次的细节。
我的一位同事告诉我,实现接口会带来开销。这是真的吗?
我不关心微优化;我只想知道这需要更深层次的细节。
无法抗拒并测试它,它看起来几乎没有开销。
参与者是:
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
从Java的角度来看,至少在最新版本的Hotspot中,答案通常是很少或没有开销。
例如,假设您有如下方法:
public void doSomethingWith(CharSequence cs) {
char ch = cs.charAt(0);
...
}
当然,CharSequence是一个接口。因此,您可能会期望该方法必须做额外的工作,检查对象类型,查找方法,并在doiing中搜索,因此可能最后搜索接口,等等 - 基本上您可以想象到的所有恐怖故事......
但实际上,VM可以比这更聪明。如果在实践中,您总是传递特定类型的对象,那么它不仅可以跳过objec类型检查,甚至可以内联该方法。例如,如果您在一系列字符串的循环中调用上述方法,Hotspot实际上可以将对charAt()的调用内联,以便从字面上获取字符成为几个MOV指令 - 换句话说,接口上的方法调用甚至可以变成根本没有方法调用。(附言此信息基于 1.6 更新 12 的调试版本的程序集输出。