【发布时间】:2011-10-25 21:05:13
【问题描述】:
我想知道在 java 中使用 instanceof 运算符的计算成本有多高,想知道是否有更好的替代方法
【问题讨论】:
-
是否有替代方案取决于您需要做什么......
标签: java performance complexity-theory
我想知道在 java 中使用 instanceof 运算符的计算成本有多高,想知道是否有更好的替代方法
【问题讨论】:
标签: java performance complexity-theory
替代方法是避免使用instanceof 并正确设计您的类(在OO 意义上)。
由于instanceof 运算符有相应的“instanceof”字节码指令,因此可能不会有更高效的方法;但这也可能取决于实际 JVM 的优化方式。
【讨论】:
instanceof 通常与糟糕的设计有关。对我来说,不使用它是最好的选择。如果您不使用它,则无需担心它的性能。
instanceof 非常快。但是,这通常是设计欠佳的表现。
它的表现与(成功的)演员大致相同,因为它做的事情大致相同。事实上,这个任务大致相当于一个“虚拟”方法调用。
关于健全的实现:对于类,只需获取运行时类并查看固定偏移量以检查超类(只要 HotSpot 的继承链不超过八个类)。接口有点棘手,但通常会缓存任何特定运行时类的最后两个用例。所以这也很快。
【讨论】:
我假设您实际上已经分析了您的代码并发现您对instanceof 的使用对性能造成了不小的影响?如果不是,那么您几乎肯定是在解决一个不值得您花时间解决的问题。
如果你所做的只是这样的代码:
if ( something instanceof MyClass ) {
MyClass mySomething = (MyClass) something;
//...
} else {
//exceptional case
}
那么也许可以先尝试演员阵容,并让ClassCastException 成为您的“例外情况”:
try {
MyClass mySomething = (MyClass) something;
} catch (ClassCastException cce) {
//exceptional case
}
现在,虽然优化可能为时过早,但重新考虑您的设计也不会为时过早。过度使用instanceof 是一种设计气味。一般来说,您应该以将使用instanceof(实际上是强制转换)的次数减少到(几乎)零的方式使用泛型和多态性。
如果应根据对象的类型运行不同的代码,请考虑使该代码成为对象的实例方法,并使不同的类型符合接口。
【讨论】:
如果您想检查对象是否是某个类的实例(但不是extends 或implements 它),也许将这些类与== 进行比较会更快:
o.getClass() == YourClass.class
否则,由于已为此特定目的创建了 instanceof 关键字,因此我看不出你还能做得更好..
【讨论】:
instanceof字节码操作。您的方法添加了方法调用getClass。
getClass 的比较将不起作用。例如,如果您有 FileReader 扩展 InputStreamReader 进而扩展/实现 Reader,则在使用 new FileReader 实例化的对象上调用 getClass 将永远不会产生除 FileReader 类之外的任何东西,因此 @987654335 @ 或 o.getClass() == InputStreamReader 都将评估为 false。另一方面,instanceof 在所有三个类案例中都会产生 true。