instanceof是如何在JAVA中实现的?

instanceof是如何在JAVA中实现的?,java,performance,instanceof,Java,Performance,Instanceof,现在我正在编写一个ORM框架,非常关注性能 在这个框架中,我必须使用instanceof和Class.isAssignableFrom来检查类型的兼容性 所以我对和类的实例的性能有点怀疑 它到底有多慢?首先,如果你要对它进行微基准测试,至少运行一个大的循环和平均值,因为你在计时中看到了很多噪音。 话虽如此,是的,反思是缓慢的。如果你能围绕它进行设计并使用其他任何东西,那么就去做。 例如,如果您要使用的类集很小,并且事先就知道了,请将它们保存在映射中,并在那里查找它们-您需要所有子类都位于该映射中

现在我正在编写一个ORM框架,非常关注性能

在这个框架中,我必须使用
instanceof
Class.isAssignableFrom
来检查类型的兼容性

所以我对
类的
实例的性能有点怀疑


它到底有多慢?

首先,如果你要对它进行微基准测试,至少运行一个大的循环和平均值,因为你在计时中看到了很多噪音。
话虽如此,是的,反思是缓慢的。如果你能围绕它进行设计并使用其他任何东西,那么就去做。
例如,如果您要使用的类集很小,并且事先就知道了,请将它们保存在
映射中,并在那里查找它们-您需要所有子类都位于该映射中,但查找速度将比实例快得多(这基本上就是许多快速序列化库避免反射的原因)

如果您不想(当然不能)提前构建此映射,您可以在运行时将其构建为缓存,然后每个新类只需要一次instanceOf调用

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

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

ALOAD 0
INSTANCEOF java/lang/Object
ISTORE 1
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
比照

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

ALOAD 0
INSTANCEOF java/lang/Object
ISTORE 1
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
instanceof是如何在JAVA中实现的

简单的回答是,它依赖于平台

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

然而,我不认为这将是特别有益的。您真正想知道的是
instanceof
还是
Class.isAssignableFrom
更快。您可以通过仔细的微观基准测试来衡量这一点

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


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

您考虑过JVM启动时间吗?这完全不像是一种可靠的基准测试技术。我认为它没有那么慢,可能是System.out.println()占用了大部分时间。您肯定应该在更大范围内运行计时测试,比如100000次。@LouisWasserman是的,我的错,JVM启动时间。@GavinXiong syso将不会被执行。。类似的问题不是关于解决方案。这是关于操作员instanceOf如何工作的最终他会意识到它很慢,他无法触及实现,他必须绕过它…instanceOf在大多数JVM中并不慢,它正在使用每个java版本进行优化。JVM使用类层次结构分析并优化IMO中的大多数instanceOf调用。@Narendra Pathai——但大多数快速序列化库(例如kryo)都以摆脱它为荣(并通过摆脱它来提高性能)。我同意,对于不经常使用,你不会感觉到,但如果你经常使用,它是显而易见的。我认为它很便宜。此外,我也找不到任何著名的作者说使用instanceof很重,你比较了instanceof和IsAssignableFrom,但我仍然不知道
instanceof
的实现。不幸的是,查看字节码并不能告诉你
instanceof
是如何实际实现的。真正的性能决定因素是JIT编译器发出的本机代码。是的,这完全取决于JVM/JIT。但是字节码对于所有JVM都是相同的。因此,我们可以关闭优化(-Xint在我的JVM上),并说原则上这段代码比那段代码快(慢),其余的取决于JVM@EvgeniyDorofeev-
-Xint
不仅仅是关闭优化。它禁用JIT编译,并完全使用解释器运行字节码。从解释代码的性能中,您根本无法得出任何关于JIT编译代码性能的合理结论。。。反之亦然。原则上没有,实践上也没有。