4

现在我正在编写一个 ORM 框架并且非常关心性能。

在这个框架中,我必须使用instanceofClass.isAssignableFrom检查类型兼容性。

instanceof所以我对和的表现有点怀疑Class.isAssignableFrom

它到底有多慢?

4

3 回答 3

7

instanceof 应该更快,它是一个字节码操作

public static void main(String[] args) {
        boolean res1 = args instanceof Object;

字节码

ALOAD 0
INSTANCEOF java/lang/Object
ISTORE 1

相比于

boolean res2 = Object.class.isAssignableFrom(args.getClass());

字节码

LDC Ljava/lang/Object;.class
ALOAD 0
INVOKEVIRTUAL java/lang/Object.getClass()Ljava/lang/Class;
INVOKEVIRTUAL java/lang/Class.isAssignableFrom(Ljava/lang/Class;)Z
ISTORE 2
于 2013-01-07T05:37:07.453 回答
3

JAVA内部是如何实现instanceof的?

简短的回答是它依赖于平台。

长答案是,您应该能够通过编写一个使用 的测试用例instanceof,在循环中运行它以确保它得到 JIT 编译,然后转储并检查本机代码来找出它是如何实现的。

但是,我认为这不会特别有指导意义。您真正想知道的是是否instanceof更快Class.isAssignableFrom。您可以通过仔细的微基准测试来衡量这一点。

FWIW,我预测您会发现它instanceof更快。(我希望 JIT 编译器能够以instanceof无法优化反射版本的方式进行优化。)

但最后,我建议您不要在这个阶段浪费时间进行这种级别的优化。使用 对此进行编码instanceof,并等到您有一些分析数据告诉您您的instanceof使用确实是性能瓶颈。(“关心性能”很好……但实际上,在性能成为关键问题之前,您需要做好更重要的事情。)

于 2013-01-07T07:06:16.720 回答
1

首先,如果您要对此进行微基准测试,请至少运行一个大循环并取平均值,因为您会在计时中看到很多噪音。
话虽如此,是的,反射很慢。如果您可以围绕它进行设计并使用其他任何东西,那就去做吧。
例如,如果您将使用的类集很小并且事先已知,请将它们保存在 a 中Map<Class,[Something]>并在那里查找它们 - 您需要所有子类都在该映射中,但查找速度会比一个 instanceof (这基本上就是很多快速序列化库如何避免反射)
如果你不想(不能)提前构建这个映射,你可以在运行时将它构建为缓存,然后你只需要调用 instanceOf 一次新班级

于 2013-01-07T05:10:46.073 回答