java - Java实例真的这么快吗?

标签 java instanceof jmh

我正在尝试测量实例是否真的很快。这是非常简单的基准:

public Object a = 2;

@Benchmark
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@Measurement(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public boolean test() {
    return a instanceof Double;
}

我跑了这条长凳

Benchmark              Mode  Cnt  Score   Error  Units
MyBenchmark.test       avgt    5  3.105 ± 0.086  ns/op

基准测试的汇编输出太长,省略。

我还写了一个简单的java程序

private static Object i = 123;

public static boolean insOf(){
    return i instanceof Double;
}

public static void main(String[] args) throws IOException {
    for (int i = 0; i < 100000000; i++)
        if(insOf())
            System.out.print("");
}

编译后的 insOf 方法的汇编输出如下:

0x00007fd761114b60: mov     %eax,0xfffffffffffec000(%rsp)
  0x00007fd761114b67: push    %rbp
  0x00007fd761114b68: sub     $0x10,%rsp        ;*synchronization entry
                                                ; - com.get.intent.App::insOf@-1 (line 24)

  0x00007fd761114b6c: movabs  $0xd6f788e0,%r10  ;   {oop(a 'java/lang/Class' = 'com/get/intent/App')}
  0x00007fd761114b76: mov     0x68(%r10),%r11d  ;*getstatic i
                                                ; - com.get.intent.App::insOf@0 (line 24)

  0x00007fd761114b7a: mov     0x8(%r11),%r10d   ; implicit exception: dispatches to 0x00007fd761114b9c
  0x00007fd761114b7e: cmp     $0x20002192,%r10d  ;   {metadata('java/lang/Double')}
  0x00007fd761114b85: jne     0x7fd761114b98          <-------- HERE!!!
  0x00007fd761114b87: mov     $0x1,%eax
  0x00007fd761114b8c: add     $0x10,%rsp
  0x00007fd761114b90: pop     %rbp
  0x00007fd761114b91: test    %eax,0x16774469(%rip)  ;   {poll_return}
  0x00007fd761114b97: retq
  0x00007fd761114b98: xor     %eax,%eax
  0x00007fd761114b9a: jmp     0x7fd761114b8c          <------- HERE!!!
  0x00007fd761114b9c: mov     $0xfffffff4,%esi
  0x00007fd761114ba1: nop
  0x00007fd761114ba3: callq   0x7fd7610051a0    ; OopMap{off=72}
                                                ;*instanceof
                                                ; - com.get.intent.App::insOf@3 (line 24)
                                                ;   {runtime_call}
  0x00007fd761114ba8: callq   0x7fd776591a20    ;*instanceof
                                                ; - com.get.intent.App::insOf@3 (line 24)
                                                ;   {runtime_call}

省略了大量的hlt指令。

据我所知,实例 of 大约有 10 条汇编指令,其中有两个跳转(jnejmp)。跳跃有点令人困惑。为什么我们需要它们?

问题:Java instance of 真的这么快吗?

最佳答案

好吧,您正在涉足反汇编,因此您可能必须重建这些跳转所代表的函数。使用源代码可用且具有调试符号的 JVM 可能是个好主意。

仅基于 instanceof 的语义,我认为这些跳转所做的就是对父类(super class)递归执行相同的测试(因为基本上 instanceof 可以编写为函数伪代码为 instanceof(object, class) = class != null and (object.class == class or instanceof(object.class.superclass, class) or instanceof(any object.class.interface, class))

关于java - Java实例真的这么快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46912850/

相关文章:

java - 为什么我的 oauth2 配置没有使用我的自定义 UserService?

java - 使用来自另一个 ArrayList 的映射实例化 ArrayList

java - 为什么用于斐波那契计算的简单 Scala tailrec 循环比 Java 循环快 3 倍?

java - 通过对排序键执行 IN 操作 (begins_with (condition-expression )) 来查询 dynamoDB

java - 向已通过身份验证的用户添加新角色(无需将其注销)

java - 检查一个类是否是 java.lang.Enum

java - 在 HashMap 中 remove() 比 get() 快吗?

java - JMH:以 json 对象的形式返回基准测试结果

java - 如何在Android中使用SmsManager发送具有自定义线程ID的短信?

java - 在按类类型或接口(interface)收集实例的情况下如何替换 instanceof