Java 中的链接方法很慢吗?

2023-12-11

假设我有一个对象A哪个可以调用getB() call getC() call getD()调用 doSomething... 现在我想使用一些方法D在我的应用程序中多次,即

 A.getB().getC().getD().doSomething1();
 A.getB().getC().getD().doSomething2();
 A.getB().getC().getD().doSomething3();

我知道最好创建一个变量d = A.getB().getC().getD()然后使用它。但我想知道像这样链接多个方法是否存在任何性能问题。

class A { 
  private B b;
  B getB() { 
    return b;
  }
}
class B {
  private C c;
  C getC() { 
    return c;
  }
}
class C {
  private D d;
  D getD() { 
    return d;
  }
}

class D {
  void doSomething1(){};
  void doSomething2(){};
  void doSomething3(){};
}

尽管您提到您已经知道了:您应该避免这么长的方法链,原因有几个:

  • 这表明了糟糕的 OO 设计(更准确地说,它看起来违反了德墨忒耳定律)
  • 这是很容易出错的。如果一行像a.getB().getC().getD().doSomething()抛出一个NullPointerException,你不会有调试这个的乐趣......
  • 让我在这里说一点主观的话:它看起来很糟糕。

当然,你还得考虑what这些方法实际上正在做。虽然一个get-方法通常应该只返回一个值,你不知道它是否真的这样做。甚至像

List<T> getList() {
    // Return an unmodifiable view to the caller
    return Collections.unmodifiableList(internalList);
}

(这当然is一个好的做法)可能会改变结果。

话虽这么说,并考虑到这些get-方法真的很简单,很愚蠢Getters:

它不会对实践中的性能产生影响。方法调用将由 JIT 内联。

例如,考虑以下程序:

class ChainA {
  private ChainB b = new ChainB();
  ChainB getB() {
    return b;
  }
}
class ChainB {
  private ChainC c = new ChainC();
  ChainC getC() {
    return c;
  }
}
class ChainC {
  private ChainD d = new ChainD();
  ChainD getD() {
    return d;
  }
}

class ChainD {
  private int result = 0;
  int getResult() { return result; }
  void doSomething1(){ result += 1; }
  void doSomething2(){ result += 2; }
  void doSomething3(){ result += 3; }
}

class Chaining
{
    public static void main(String args[])
    {
        for (int n=100; n<10000; n+=100)
        {
            ChainA a0 = new ChainA();
            runChained(a0, n);
            System.out.println(a0.getB().getC().getD().getResult());

            ChainA a1 = new ChainA();
            runUnChained(a1, n);
            System.out.println(a1.getB().getC().getD().getResult());
        }

    }

    private static void runChained(ChainA a, int n)
    {
        for (int i=0; i<n; i++)
        {
            a.getB().getC().getD().doSomething1();
            a.getB().getC().getD().doSomething2();
            a.getB().getC().getD().doSomething3();
        }
    }

    private static void runUnChained(ChainA a, int n)
    {
        ChainD d = a.getB().getC().getD();
        for (int i=0; i<n; i++)
        {
            d.doSomething1();
            d.doSomething2();
            d.doSomething3();
        }
    }

}

它像您所描述的那样执行调用,一次作为链式调用,一次作为非链式版本。

运行它

java -server -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly Chaining

在启用 HotSpot-Disassembler 的 JVM 上会产生以下输出(无需read仅供参考)

链式运行:

Decoding compiled method 0x0000000002885d50:
Code:
[Entry Point]
[Verified Entry Point]
[Constants]
  # {method} {0x0000000055360550} &apos;runChained&apos; &apos;(LChainA;I)V&apos; in &apos;Chaining&apos;
  # parm0:    rdx:rdx   = &apos;ChainA&apos;
  # parm1:    r8        = int
  #           [sp+0x30]  (sp of caller)
  0x0000000002885e80: mov    %eax,-0x6000(%rsp)
  0x0000000002885e87: push   %rbp
  0x0000000002885e88: sub    $0x20,%rsp         ;*synchronization entry
                                                ; - Chaining::runChained@-1 (line 47)

  0x0000000002885e8c: mov    %rdx,%r9
  0x0000000002885e8f: mov    %r8d,%ebx
  0x0000000002885e92: test   %r8d,%r8d
  0x0000000002885e95: jle    0x0000000002885f8a  ;*if_icmpge
                                                ; - Chaining::runChained@4 (line 47)

  0x0000000002885e9b: mov    0xc(%rdx),%r11d    ;*getfield b
                                                ; - ChainA::getB@1 (line 4)
                                                ; - Chaining::runChained@8 (line 49)
                                                ; implicit exception: dispatches to 0x0000000002885f96
  0x0000000002885e9f: mov    0xc(%r11),%r10d    ;*getfield c
                                                ; - ChainB::getC@1 (line 10)
                                                ; - Chaining::runChained@11 (line 49)
                                                ; implicit exception: dispatches to 0x0000000002885f96

    0x0000000002885ea3: mov    0xc(%r10),%edx     ;*getfield d
                                                ; - ChainC::getD@1 (line 16)
                                                ; - Chaining::runChained@14 (line 49)
                                                ; implicit exception: dispatches to 0x0000000002885f96
  0x0000000002885ea7: mov    0xc(%rdx),%r11d    ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runChained@17 (line 49)
                                                ; implicit exception: dispatches to 0x0000000002885f96
  0x0000000002885eab: xor    %r10d,%r10d
  0x0000000002885eae: xor    %esi,%esi
  0x0000000002885eb0: xor    %r8d,%r8d
  0x0000000002885eb3: xor    %ecx,%ecx          ;*aload_0
                                                ; - Chaining::runChained@7 (line 49)

  0x0000000002885eb5: add    %r11d,%esi         ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runChained@17 (line 49)

  0x0000000002885eb8: add    %ecx,%r8d
  0x0000000002885ebb: mov    %esi,%eax
  0x0000000002885ebd: add    $0x6,%eax          ;*iadd
                                                ; - ChainD::doSomething3@6 (line 25)
                                                ; - Chaining::runChained@43 (line 51)

  0x0000000002885ec0: mov    %eax,0xc(%rdx)     ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runChained@43 (line 51)

  0x0000000002885ec3: mov    %r10d,%edi
  0x0000000002885ec6: inc    %edi               ;*iinc
                                                ; - Chaining::runChained@46 (line 47)

  0x0000000002885ec8: cmp    $0x1,%edi
  0x0000000002885ecb: jge    0x0000000002885eee  ;*if_icmpge
                                                ; - Chaining::runChained@4 (line 47)

  0x0000000002885ecd: mov    %r10d,%ecx
  0x0000000002885ed0: shl    %ecx
  0x0000000002885ed2: mov    %r8d,%esi
  0x0000000002885ed5: add    $0x6,%esi
  0x0000000002885ed8: mov    %ecx,%r8d
  0x0000000002885edb: add    $0x2,%r8d
  0x0000000002885edf: shl    $0x2,%r10d
  0x0000000002885ee3: mov    %r10d,%ecx
  0x0000000002885ee6: add    $0x4,%ecx
  0x0000000002885ee9: mov    %edi,%r10d
  0x0000000002885eec: jmp    0x0000000002885eb5
  0x0000000002885eee: mov    %ebx,%r11d
  0x0000000002885ef1: add    $0xfffffff1,%r11d
  0x0000000002885ef5: mov    $0x80000000,%r9d
  0x0000000002885efb: cmp    %r11d,%ebx
  0x0000000002885efe: cmovl  %r9d,%r11d
  0x0000000002885f02: cmp    %r11d,%edi
  0x0000000002885f05: jge    0x0000000002885f3c
  0x0000000002885f07: sub    %r8d,%esi
  0x0000000002885f0a: nopw   0x0(%rax,%rax,1)   ;*aload_0
                                                ; - Chaining::runChained@7 (line 49)

  0x0000000002885f10: mov    %edi,%r8d
  0x0000000002885f13: shl    %r8d
  0x0000000002885f16: mov    %edi,%r9d
  0x0000000002885f19: shl    $0x2,%r9d
  0x0000000002885f1d: add    %r9d,%r8d
  0x0000000002885f20: add    %esi,%r8d          ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runChained@17 (line 49)

  0x0000000002885f23: mov    %r8d,%eax
  0x0000000002885f26: add    $0x60,%eax         ;*iadd
                                                ; - ChainD::doSomething3@6 (line 25)
                                                ; - Chaining::runChained@43 (line 51)

  0x0000000002885f29: add    $0x5a,%r8d
  0x0000000002885f2d: mov    %r8d,0xc(%rdx)
  0x0000000002885f31: mov    %eax,0xc(%rdx)     ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runChained@43 (line 51)

  0x0000000002885f34: add    $0x10,%edi         ;*iinc
                                                ; - Chaining::runChained@46 (line 47)

  0x0000000002885f37: cmp    %r11d,%edi
  0x0000000002885f3a: jl     0x0000000002885f10  ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runChained@17 (line 49)

  0x0000000002885f3c: cmp    %ebx,%edi
  0x0000000002885f3e: jge    0x0000000002885f8a
  0x0000000002885f40: mov    %edi,%r10d
  0x0000000002885f43: shl    $0x2,%r10d
  0x0000000002885f47: mov    %edi,%r11d
  0x0000000002885f4a: shl    %r11d
  0x0000000002885f4d: mov    %r11d,%r8d
  0x0000000002885f50: add    %r10d,%r8d
  0x0000000002885f53: sub    %r8d,%eax
  0x0000000002885f56: xchg   %ax,%ax            ;*aload_0
                                                ; - Chaining::runChained@7 (line 49)

  0x0000000002885f58: add    %r11d,%r10d
  0x0000000002885f5b: add    %eax,%r10d
  0x0000000002885f5e: add    $0x6,%r10d
  0x0000000002885f62: mov    %r10d,0xc(%rdx)    ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runChained@43 (line 51)

  0x0000000002885f66: mov    %edi,%r8d
  0x0000000002885f69: inc    %r8d               ;*iinc
                                                ; - Chaining::runChained@46 (line 47)

  0x0000000002885f6c: cmp    %ebx,%r8d
  0x0000000002885f6f: jge    0x0000000002885f8a
  0x0000000002885f71: mov    %edi,%r10d
  0x0000000002885f74: shl    $0x2,%r10d
  0x0000000002885f78: shl    %edi
  0x0000000002885f7a: add    $0x4,%r10d
  0x0000000002885f7e: mov    %edi,%r11d
  0x0000000002885f81: add    $0x2,%r11d
  0x0000000002885f85: mov    %r8d,%edi
  0x0000000002885f88: jmp    0x0000000002885f58  ;*if_icmpge
                                                ; - Chaining::runChained@4 (line 47)

  0x0000000002885f8a: add    $0x20,%rsp
  0x0000000002885f8e: pop    %rbp
  0x0000000002885f8f: test   %eax,-0x26c5f95(%rip)        # 0x00000000001c0000
                                                ;   {poll_return}
  0x0000000002885f95: retq   
  0x0000000002885f96: mov    $0xffffff86,%edx
  0x0000000002885f9b: mov    %r9,%rbp
  0x0000000002885f9e: mov    %r8d,(%rsp)
  0x0000000002885fa2: nop
  0x0000000002885fa3: callq  0x00000000027b7320  ; OopMap{rbp=Oop off=296}
                                                ;*aload_0
                                                ; - Chaining::runChained@7 (line 49)
                                                ;   {runtime_call}
  0x0000000002885fa8: int3                      ;*aload_0
                                                ; - Chaining::runChained@7 (line 49)

  0x0000000002885fa9: hlt    
  0x0000000002885faa: hlt    
  0x0000000002885fab: hlt    
  0x0000000002885fac: hlt    
  0x0000000002885fad: hlt    
  0x0000000002885fae: hlt    
  0x0000000002885faf: hlt    
  0x0000000002885fb0: hlt    
  0x0000000002885fb1: hlt    
  0x0000000002885fb2: hlt    
  0x0000000002885fb3: hlt    
  0x0000000002885fb4: hlt    
  0x0000000002885fb5: hlt    
  0x0000000002885fb6: hlt    
  0x0000000002885fb7: hlt    
  0x0000000002885fb8: hlt    
  0x0000000002885fb9: hlt    
  0x0000000002885fba: hlt    
  0x0000000002885fbb: hlt    
  0x0000000002885fbc: hlt    
  0x0000000002885fbd: hlt    
  0x0000000002885fbe: hlt    
  0x0000000002885fbf: hlt    
[Exception Handler]
[Stub Code]
  0x0000000002885fc0: jmpq   0x00000000028694a0  ;   {no_reloc}
[Deopt Handler Code]
  0x0000000002885fc5: callq  0x0000000002885fca
  0x0000000002885fca: subq   $0x5,(%rsp)
  0x0000000002885fcf: jmpq   0x00000000027b6f40  ;   {runtime_call}
  0x0000000002885fd4: hlt    
  0x0000000002885fd5: hlt    
  0x0000000002885fd6: hlt    
  0x0000000002885fd7: hlt    

不受束缚地运行:

Decoding compiled method 0x00000000028893d0:
Code:
[Entry Point]
[Verified Entry Point]
[Constants]
  # {method} {0x0000000055360628} &apos;runUnChained&apos; &apos;(LChainA;I)V&apos; in &apos;Chaining&apos;
  # parm0:    rdx:rdx   = &apos;ChainA&apos;
  # parm1:    r8        = int
  #           [sp+0x30]  (sp of caller)
  0x0000000002889500: mov    %eax,-0x6000(%rsp)
  0x0000000002889507: push   %rbp
  0x0000000002889508: sub    $0x20,%rsp         ;*synchronization entry
                                                ; - Chaining::runUnChained@-1 (line 57)



  0x000000000288950c: mov    0xc(%rdx),%r11d    ;*getfield b
                                                ; - ChainA::getB@1 (line 4)
                                                ; - Chaining::runUnChained@1 (line 57)
                                                ; implicit exception: dispatches to 0x0000000002889612
  0x0000000002889510: mov    0xc(%r11),%r10d    ;*getfield c
                                                ; - ChainB::getC@1 (line 10)
                                                ; - Chaining::runUnChained@4 (line 57)
                                                ; implicit exception: dispatches to 0x000000000288961d
  0x0000000002889514: mov    0xc(%r10),%ebx     ;*getfield d
                                                ; - ChainC::getD@1 (line 16)
                                                ; - Chaining::runUnChained@7 (line 57)
                                                ; implicit exception: dispatches to 0x0000000002889629
  0x0000000002889518: mov    %r8d,%esi
  0x000000000288951b: test   %r8d,%r8d
  0x000000000288951e: jle    0x0000000002889606  ;*if_icmpge
                                                ; - Chaining::runUnChained@15 (line 58)

  0x0000000002889524: mov    0xc(%rbx),%r10d    ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runUnChained@19 (line 60)
                                                ; implicit exception: dispatches to 0x0000000002889635
  0x0000000002889528: xor    %r8d,%r8d
  0x000000000288952b: xor    %edx,%edx
  0x000000000288952d: xor    %r9d,%r9d
  0x0000000002889530: xor    %r11d,%r11d        ;*aload_2
                                                ; - Chaining::runUnChained@18 (line 60)

  0x0000000002889533: add    %r10d,%edx         ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runUnChained@19 (line 60)

  0x0000000002889536: add    %r11d,%r9d
  0x0000000002889539: mov    %edx,%edi
  0x000000000288953b: add    $0x6,%edi          ;*iadd
                                                ; - ChainD::doSomething3@6 (line 25)
                                                ; - Chaining::runUnChained@27 (line 62)

  0x000000000288953e: mov    %edi,0xc(%rbx)     ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runUnChained@27 (line 62)

  0x0000000002889541: mov    %r8d,%ecx
  0x0000000002889544: inc    %ecx               ;*iinc
                                                ; - Chaining::runUnChained@30 (line 58)

  0x0000000002889546: cmp    $0x1,%ecx
  0x0000000002889549: jge    0x000000000288956e  ;*if_icmpge
                                                ; - Chaining::runUnChained@15 (line 58)

  0x000000000288954b: mov    %r8d,%r11d
  0x000000000288954e: shl    %r11d
  0x0000000002889551: mov    %r9d,%edx
  0x0000000002889554: add    $0x6,%edx
  0x0000000002889557: mov    %r11d,%r9d
  0x000000000288955a: add    $0x2,%r9d
  0x000000000288955e: shl    $0x2,%r8d
  0x0000000002889562: mov    %r8d,%r11d
  0x0000000002889565: add    $0x4,%r11d
  0x0000000002889569: mov    %ecx,%r8d
  0x000000000288956c: jmp    0x0000000002889533
  0x000000000288956e: mov    %esi,%r10d
  0x0000000002889571: add    $0xfffffff1,%r10d
  0x0000000002889575: mov    $0x80000000,%r11d
  0x000000000288957b: cmp    %r10d,%esi
  0x000000000288957e: cmovl  %r11d,%r10d
  0x0000000002889582: cmp    %r10d,%ecx
  0x0000000002889585: jge    0x00000000028895bc
  0x0000000002889587: sub    %r9d,%edx
  0x000000000288958a: nopw   0x0(%rax,%rax,1)   ;*aload_2
                                                ; - Chaining::runUnChained@18 (line 60)

  0x0000000002889590: mov    %ecx,%r11d
  0x0000000002889593: shl    %r11d
  0x0000000002889596: mov    %ecx,%r8d
  0x0000000002889599: shl    $0x2,%r8d
  0x000000000288959d: add    %r8d,%r11d
  0x00000000028895a0: add    %edx,%r11d         ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runUnChained@19 (line 60)

  0x00000000028895a3: mov    %r11d,%edi
  0x00000000028895a6: add    $0x60,%edi         ;*iadd
                                                ; - ChainD::doSomething3@6 (line 25)
                                                ; - Chaining::runUnChained@27 (line 62)

  0x00000000028895a9: add    $0x5a,%r11d
  0x00000000028895ad: mov    %r11d,0xc(%rbx)
  0x00000000028895b1: mov    %edi,0xc(%rbx)     ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runUnChained@27 (line 62)

  0x00000000028895b4: add    $0x10,%ecx         ;*iinc
                                                ; - Chaining::runUnChained@30 (line 58)

  0x00000000028895b7: cmp    %r10d,%ecx
  0x00000000028895ba: jl     0x0000000002889590  ;*getfield result
                                                ; - ChainD::doSomething1@2 (line 23)
                                                ; - Chaining::runUnChained@19 (line 60)

  0x00000000028895bc: cmp    %esi,%ecx
  0x00000000028895be: jge    0x0000000002889606
  0x00000000028895c0: mov    %ecx,%r11d
  0x00000000028895c3: shl    $0x2,%r11d
  0x00000000028895c7: mov    %ecx,%r8d
  0x00000000028895ca: shl    %r8d
  0x00000000028895cd: mov    %r8d,%r9d
  0x00000000028895d0: add    %r11d,%r9d
  0x00000000028895d3: sub    %r9d,%edi
  0x00000000028895d6: xchg   %ax,%ax            ;*aload_2
                                                ; - Chaining::runUnChained@18 (line 60)

  0x00000000028895d8: add    %r8d,%r11d
  0x00000000028895db: add    %edi,%r11d
  0x00000000028895de: add    $0x6,%r11d
  0x00000000028895e2: mov    %r11d,0xc(%rbx)    ;*putfield result
                                                ; - ChainD::doSomething3@7 (line 25)
                                                ; - Chaining::runUnChained@27 (line 62)

  0x00000000028895e6: mov    %ecx,%edx
  0x00000000028895e8: inc    %edx               ;*iinc
                                                ; - Chaining::runUnChained@30 (line 58)

  0x00000000028895ea: cmp    %esi,%edx
  0x00000000028895ec: jge    0x0000000002889606
  0x00000000028895ee: mov    %ecx,%r11d
  0x00000000028895f1: shl    $0x2,%r11d
  0x00000000028895f5: shl    %ecx
  0x00000000028895f7: add    $0x4,%r11d
  0x00000000028895fb: mov    %ecx,%r8d
  0x00000000028895fe: add    $0x2,%r8d
  0x0000000002889602: mov    %edx,%ecx
  0x0000000002889604: jmp    0x00000000028895d8  ;*if_icmpge
                                                ; - Chaining::runUnChained@15 (line 58)

  0x0000000002889606: add    $0x20,%rsp
  0x000000000288960a: pop    %rbp
  0x000000000288960b: test   %eax,-0x26c9611(%rip)        # 0x00000000001c0000
                                                ;   {poll_return}
  0x0000000002889611: retq   
  0x0000000002889612: mov    $0xfffffff6,%edx
  0x0000000002889617: callq  0x00000000027b7320  ; OopMap{off=284}
                                                ;*invokevirtual getB
                                                ; - Chaining::runUnChained@1 (line 57)
                                                ;   {runtime_call}
  0x000000000288961c: int3                      ;*invokevirtual getB
                                                ; - Chaining::runUnChained@1 (line 57)

  0x000000000288961d: mov    $0xfffffff6,%edx
  0x0000000002889622: nop
  0x0000000002889623: callq  0x00000000027b7320  ; OopMap{off=296}
                                                ;*invokevirtual getC
                                                ; - Chaining::runUnChained@4 (line 57)
                                                ;   {runtime_call}
  0x0000000002889628: int3                      ;*invokevirtual getC
                                                ; - Chaining::runUnChained@4 (line 57)

  0x0000000002889629: mov    $0xfffffff6,%edx
  0x000000000288962e: nop
  0x000000000288962f: callq  0x00000000027b7320  ; OopMap{off=308}
                                                ;*invokevirtual getD
                                                ; - Chaining::runUnChained@7 (line 57)
                                                ;   {runtime_call}
  0x0000000002889634: int3                      ;*invokevirtual getD
                                                ; - Chaining::runUnChained@7 (line 57)

  0x0000000002889635: mov    $0xffffff86,%edx
  0x000000000288963a: mov    %ebx,%ebp
  0x000000000288963c: mov    %r8d,(%rsp)
  0x0000000002889640: data32 xchg %ax,%ax
  0x0000000002889643: callq  0x00000000027b7320  ; OopMap{rbp=NarrowOop off=328}
                                                ;*aload_2
                                                ; - Chaining::runUnChained@18 (line 60)
                                                ;   {runtime_call}
  0x0000000002889648: int3                      ;*aload_2
                                                ; - Chaining::runUnChained@18 (line 60)

  0x0000000002889649: hlt    
  0x000000000288964a: hlt    
  0x000000000288964b: hlt    
  0x000000000288964c: hlt    
  0x000000000288964d: hlt    
  0x000000000288964e: hlt    
  0x000000000288964f: hlt    
  0x0000000002889650: hlt    
  0x0000000002889651: hlt    
  0x0000000002889652: hlt    
  0x0000000002889653: hlt    
  0x0000000002889654: hlt    
  0x0000000002889655: hlt    
  0x0000000002889656: hlt    
  0x0000000002889657: hlt    
  0x0000000002889658: hlt    
  0x0000000002889659: hlt    
  0x000000000288965a: hlt    
  0x000000000288965b: hlt    
  0x000000000288965c: hlt    
  0x000000000288965d: hlt    
  0x000000000288965e: hlt    
  0x000000000288965f: hlt    
[Exception Handler]
[Stub Code]
  0x0000000002889660: jmpq   0x00000000028694a0  ;   {no_reloc}
[Deopt Handler Code]
  0x0000000002889665: callq  0x000000000288966a
  0x000000000288966a: subq   $0x5,(%rsp)
  0x000000000288966f: jmpq   0x00000000027b6f40  ;   {runtime_call}
  0x0000000002889674: hlt    
  0x0000000002889675: hlt    
  0x0000000002889676: hlt    
  0x0000000002889677: hlt    

通过比较输出,可以看出它们基本上是相等的。在这两种情况下,调用都是内联的。

现在人们可以争辩说doSomething方法是如此琐碎以至于they也已内联,对于更复杂的结果可能会有所不同doSomething方法。这可能是真的。但是用类似的方法进行快速测试

int doSomething(int i)
{
    List<Integer> list = new ArrayList<Integer>(
        Arrays.asList(1,2,3,4,5,6,7,8,9,10));
    Collections.sort(list);
    return list.get(i);
}

表明链式调用的实际内联仍然发生,并且当“内部”方法变得更加复杂时,任何潜在的开销might与中所做的相比,由于链式调用而发生的情况将变得可以忽略不计doSomething method.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中的链接方法很慢吗? 的相关文章

随机推荐