java class isassignablefrom_实例与Class.isAssignableFrom(…)的区别是什么??

就表演而言:

TL;DR

使用isInstance或例有相似的表现。从稍微慢一点。

按性能排序:isInstance

例 (+ 0.5%)

从 (+ 2.7%)

基于Java 8 Windows x64上2000次迭代的基准,有20次热身迭代。

理论上

使用软的字节码查看器我们可以将每个操作符转换为字节码。

在以下方面:package foo;

public class Benchmark

{

public static final Object a = new A();

public static final Object b = new B();

...

}

Java:b instanceof A;

字节码:getstatic foo/Benchmark.b:java.lang.Object

instanceof foo/A

Java:A.class.isInstance(b);

字节码:ldc Lfoo/A; (org.objectweb.asm.Type)

getstatic foo/Benchmark.b:java.lang.Object

invokevirtual java/lang/Class isInstance((Ljava/lang/Object;)Z);

Java:A.class.isAssignableFrom(b.getClass());

字节码:ldc Lfoo/A; (org.objectweb.asm.Type)

getstatic foo/Benchmark.b:java.lang.Object

invokevirtual java/lang/Object getClass(()Ljava/lang/Class;);

invokevirtual java/lang/Class isAssignableFrom((Ljava/lang/Class;)Z);

测量每个操作符使用多少字节码指令,我们可以预期。例和isInstance比从..但是,实际性能不是由字节码决定的,而是由机器代码(与平台有关)决定的。让我们为每个操作符做一个微基准。

基准

信用:正如@Aleksandr-duinsky所建议的,感谢@yura提供了基本代码,下面是一个JMH基准(参见调谐导轨):class A {}

class B extends A {}

public class Benchmark {

public static final Object a = new A();

public static final Object b = new B();

@Benchmark

@BenchmarkMode(Mode.Throughput)

@OutputTimeUnit(TimeUnit.MICROSECONDS)

public boolean testInstanceOf()

{

return b instanceof A;

}

@Benchmark

@BenchmarkMode(Mode.Throughput)

@OutputTimeUnit(TimeUnit.MICROSECONDS)

public boolean testIsInstance()

{

return A.class.isInstance(b);

}

@Benchmark

@BenchmarkMode(Mode.Throughput)

@OutputTimeUnit(TimeUnit.MICROSECONDS)

public boolean testIsAssignableFrom()

{

return A.class.isAssignableFrom(b.getClass());

}

public static void main(String[] args) throws RunnerException {

Options opt = new OptionsBuilder()

.include(TestPerf2.class.getSimpleName())

.warmupIterations(20)

.measurementIterations(2000)

.forks(1)

.build();

new Runner(opt).run();

}

}

给出了以下结果(分数为一个时间单位中的许多操作,所以分数越高越好):Benchmark                       Mode   Cnt    Score   Error   Units

Benchmark.testIsInstance        thrpt  2000  373,061 ± 0,115  ops/us

Benchmark.testInstanceOf        thrpt  2000  371,047 ± 0,131  ops/us

Benchmark.testIsAssignableFrom  thrpt  2000  363,648 ± 0,289  ops/us

警告基准测试是JVM和平台依赖的。由于每个操作之间没有显着性差异,所以可能会得到不同的结果(也可能是不同的顺序!)在不同的Java版本和/或平台上,如Solaris、Mac或Linux。

当“B直接扩展A”时,基准比较了“isB是A的一个实例”的性能。如果类层次更深、更复杂(如B扩展X,扩展Y,扩展Z,扩展A),则结果可能不同。

通常建议首先编写代码,选择一个操作符(最方便),然后分析代码,以检查是否存在性能瓶颈。也许这个操作符在你的代码中是可以忽略不计的,或者.

关于前一点,

instanceof在您的代码上下文中,可能比

isInstance例如.。

为了给出一个例子,请使用下面的循环:class A{}

class B extends A{}

A b = new B();

boolean execute(){

return A.class.isAssignableFrom(b.getClass());

// return A.class.isInstance(b);

// return b instanceof A;

}

// Warmup the code

for (int i = 0; i 

execute();

// Time it

int count = 100000;

final long start = System.nanoTime();

for(int i=0; i

execute();

}

final long elapsed = System.nanoTime() - start;

由于有了JIT,代码在某种程度上得到了优化,我们得到:实例:6ms

isInstance:12 ms

来自:15 ms

最初,这篇文章使用一个为循环在原始Java中,这给出了不可靠的结果,因为有些优化就像在时间上一样,可以消除循环。因此,它主要是测量JIT编译器对循环进行优化所花费的时间:独立于迭代次数的性能测试想了解更多细节

相关问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值