现在我正在编写一个 ORM 框架并且非常关心性能。
在这个框架中,我必须使用instanceof
并Class.isAssignableFrom
检查类型兼容性。
instanceof
所以我对和的表现有点怀疑Class.isAssignableFrom
它到底有多慢?
现在我正在编写一个 ORM 框架并且非常关心性能。
在这个框架中,我必须使用instanceof
并Class.isAssignableFrom
检查类型兼容性。
instanceof
所以我对和的表现有点怀疑Class.isAssignableFrom
它到底有多慢?
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
JAVA内部是如何实现instanceof的?
简短的回答是它依赖于平台。
长答案是,您应该能够通过编写一个使用 的测试用例instanceof
,在循环中运行它以确保它得到 JIT 编译,然后转储并检查本机代码来找出它是如何实现的。
但是,我认为这不会特别有指导意义。您真正想知道的是是否instanceof
更快Class.isAssignableFrom
。您可以通过仔细的微基准测试来衡量这一点。
FWIW,我预测您会发现它instanceof
更快。(我希望 JIT 编译器能够以instanceof
无法优化反射版本的方式进行优化。)
但最后,我建议您不要在这个阶段浪费时间进行这种级别的优化。使用 对此进行编码instanceof
,并等到您有一些分析数据告诉您您的instanceof
使用确实是性能瓶颈。(“关心性能”很好……但实际上,在性能成为关键问题之前,您需要做好更重要的事情。)
首先,如果您要对此进行微基准测试,请至少运行一个大循环并取平均值,因为您会在计时中看到很多噪音。
话虽如此,是的,反射很慢。如果您可以围绕它进行设计并使用其他任何东西,那就去做吧。
例如,如果您将使用的类集很小并且事先已知,请将它们保存在 a 中Map<Class,[Something]>
并在那里查找它们 - 您需要所有子类都在该映射中,但查找速度会比一个 instanceof (这基本上就是很多快速序列化库如何避免反射)
如果你不想(不能)提前构建这个映射,你可以在运行时将它构建为缓存,然后你只需要调用 instanceOf 一次新班级