java instanceof性能差_关于性能:如何在JAVA中实现instanceof?

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

在此框架中,我必须使用instanceof和Class.isAssignableFrom来检查类型兼容性。

所以我对instanceof和Class.isAssignableFrom的性能有些怀疑

到底有多慢?

您是否考虑了JVM启动时间? 这与可靠的基准测试技术完全不同。

我认为并不是那么慢,可能是System.out.println()花费了大部分时间。 而且,您绝对应该更大规模地运行时序测试,例如100000次。

@LouisWasserman是的,我的错,JVM启动时间..

@GavinXiong syso将不会执行。

类似于stackoverflow.com/questions/4973359/

@NarendraPathai是的,但我看不到它是如何实现的。

我希望它在一个微基准测试中花费大约10 ns,在典型代码中花费大约40 ns(因为数据不会被很好地缓存)。在某些情况下,如果与强制转换结合使用,instanceof几乎可以消除。 通常是

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

是的,您比较了instanceof和isAssignableFrom

但是我仍然不知道instanceof的实现

不幸的是,查看字节码并不能告诉您instanceof的实际实现方式。真正的性能决定因素在于JIT编译器发出的本机代码。

是的,这一切都取决于JVM / JIT。但是字节码对于所有JVM都是相同的。因此,我们可以关闭优化功能(在我的JVM上为-Xint),并说该代码在原理上比该代码更快(更慢),其余部分取决于JVM。

@EvgeniyDorofeev--Xint并不会关闭优化。它禁用JIT编译,并完全使用解释器运行字节码。您根本无法从解释代码的性能中得出关于JIT编译代码性能的任何合理结论……反之亦然。不是原则上,不是实践。

How instanceof is implemented inside JAVA?

简短的答案是它取决于平台。

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

但是,我认为这不会特别有启发性。您真正想知道的是instanceof还是Class.isAssignableFrom更快。您可以通过仔细的微基准测试来衡量。

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

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

首先,如果您要对此进行微基准测试,则至少要运行一个大的循环并平均,因为您会在计时中看到很多噪音。

话虽如此,反射是缓慢的。如果您可以围绕它设计并使用其他任何东西,那就去做。

例如,如果要使用的类的集合很小并且事先已知,则将它们放在Map中并在其中查找-您需要所有子类都在该映射中,但是查找将是比instanceof快得多(基本上,这就是许多快速序列化库避免反射的方式)

如果您不想(无法)提前构建此地图,则可以在运行时将其构建为缓存,然后每个新类仅需要一次instanceOf调用

问题不在于解决方案。关于运算符instanceOf的工作方式

最终,地狱意识到了它的缓慢,他无法触及实现,而他必须解决它……

在大多数JVM中,instanceOf的运行速度并不慢,它已针对每种Java版本进行了优化。 JVM使用类层次分析并优化IMO的大多数instanceOf调用。

@Narendra Pathai-但是大多数快速的序列化库(例如kryo)都以摆脱它为傲(并通过提高性能来提高性能)。我同意,对于不经常使用的产品,您不会感觉到,但是,如果您大量使用它,则它会很明显。

stackoverflow.com/questions/12386789/我认为它很便宜。我也找不到任何知名的作者指出使用instanceof很繁琐

@-oreilly.com/catalog/javarmi/chapter/ch10.html在"性能问题"下查看:"序列化存在三个主要的性能问题:它依赖于反射,它具有令人难以置信的冗长……"。是的,它越来越好,但是如果您解决它,事情总是会更快。同样,仅存在诸如code.google.com/p/reflectasm之类的东西也是一个线索。

我同意这样一个事实,即如果设计允许您必须首先对其进行更改,但是在某些情况下,您必须退回到instanceof运算符。例如:在我的一个项目中,我必须扩展Thread类,然后当我想检查它是否是我的类的实例时,我必须使用它:(如果要扩展库,那么我猜没有选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值