我正在开发一个应用程序,其中一种设计方法涉及大量使用 instanceof
运算符。虽然我知道 OO 设计通常会尽量避免使用 instanceof
,但这是另一回事,这个问题完全与性能有关。我想知道是否有任何性能影响?和 ==
一样快吗?
例如,我有一个包含 10 个子类的基类。在接受基类的单个函数中,我会检查该类是否是子类的实例并执行一些例程。
我想到的解决它的其他方法之一是改用“type id”整数原语,并使用位掩码来表示子类的类别,然后对子类“type id”进行位掩码比较"到表示类别的常量掩码。
JVM 是否以某种方式优化了 instanceof
以使其更快?我想坚持使用 Java,但应用程序的性能至关重要。如果以前曾经走过这条路的人可以提供一些建议,那就太酷了。是我吹毛求疵还是专注于错误的优化?
方法
我写了 a benchmark program评估不同的实现:
instanceof
实现(作为引用)
- 通过抽象类和
@Override
测试方法实现面向对象
- 使用自己的类型实现
getClass() == _.class
实现
我使用了 jmh使用 100 次预热调用、1000 次测量下的迭代和 10 次 fork 运行基准测试。因此,每个选项都测量了 10 000 次,这需要 12:18:57 在我的 MacBook Pro 上运行 macOS 10.12.4 和 Java 1.8 的整个基准测试。基准测量每个选项的平均时间。更多详情见my implementation on GitHub .
为了完整起见:有一个 previous version of this answer and my benchmark .
结果
| Operation | Runtime in nanoseconds per operation | Relative to instanceof ||------------|--------------------------------------|------------------------|| INSTANCEOF | 39,598 ± 0,022 ns/op | 100,00 % || GETCLASS | 39,687 ± 0,021 ns/op | 100,22 % || TYPE | 46,295 ± 0,026 ns/op | 116,91 % || OO | 48,078 ± 0,026 ns/op | 121,42 % |
tl;博士
在 Java 1.8 中,instanceof
是最快的方法,尽管 getClass()
非常接近。
我是一名优秀的程序员,十分优秀!