繁体   English   中英

Java中的链接方法是否很慢?

[英]Is Chaining methods in Java slow?

假设我有一个对象A,可以调用getB()调用getC()调用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(){};
}

如果对象实例化一次,则不会有任何性能问题。 当您调用getB()。getC()...时,您仅获得对象上的链接,该链接非常快速且简单。 但是,实际上,这样的代码看起来不是很好。

尽管您已经提到了这一点,但由于以下几个原因,应避免使用如此长的方法链:

  • 这表明OO设计不良(更确切地说,它看起来像是违反了Demeter法则
  • 容易出错。 如果像a.getB().getC().getD().doSomething()抛出NullPointerException ,则调试此程序将毫无乐趣。
  • 让我在这里有点主观:它看起来太可怕了。

当然,你要考虑什么方法实际上是做。 尽管get -method通常应该只返回一个值,但您不知道它是否真的这样做。 甚至像

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

(这当然一个好习惯)可能会改变结果。

话虽如此,并考虑到这些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链接

在启用了HotSpot-Disassembler的JVM上的结果为以下输出(无需阅读 ,仅供参考)

runChained:

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    

runUnChained:

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方法是如此琐碎,以至于它们也已被内联,对于更复杂的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);
}

显示了链接调用的实际内联仍然发生,并且当“内部”方法变得更加复杂时,与doSomething方法相比,可以忽略由于链接调用而可能发生的任何潜在开销。

什么是“慢”

显然比读取局部变量的值要慢,但是除此之外,方法调用非常快,您不必担心。

另一方面,像A.getB().getC().getD().doSomething1()尖叫着进行重构。 至少在类A添加一个新方法,该方法返回D或直接调用doSomething1()

每个方法调用,操作,赋值或大多数其他操作都是对处理器的滴答。 您提供的示例可能运行得很快。 但是对处理器的每次滴答声都会开始使其变慢。 游戏开发人员对此非常关注,因为他们需要能够保持帧速率上升。 但是一般和业务应用程序对此并没有那么担心。

关键是:如果有很多链接,或者链接的方法必须做很多工作,链接将开始影响性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM