1 回答

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊
Java 和 Golang 程序在執(zhí)行之前都被編譯成機(jī)器語言——這就是 JIT 代表 Java VM 的意思。至于性能比較,每個(gè)生成的機(jī)器碼之間肯定有不那么細(xì)微的差異。
不幸的是,我無法訪問 Java JIT 編譯器生成的機(jī)器碼,但我們可以看一下 Go 編譯器(v1.11.4-amd64)為函數(shù)生成的內(nèi)容fibonacci:
# Do the comparison
MOVQ "c", AX
CMPQ AX, $2
JGE @ELSE
# Save the func result
MOVQ AX, "r"
# Clean up and return
MOVQ 24(SP), BP
ADDQ $32, SP
RET
@ELSE:
# Compute fib(c - 2)
LEAQ -2(AX), CX
MOVQ CX, (SP)
CALL fibonacci
# Save the call result
MOVQ 8(SP), AX
MOVQ AX, "temp"
# Compute fib(c - 1)
MOVQ "c", CX
DECQ CX
MOVQ CX, (SP)
CALL fibonacci
# Add previous results together
MOVQ 16(SP), AX
ADDQ 8(SP), AX
# Save the func result
MOVQ AX, "r"
# Clean up and return
MOVQ 24(SP), BP
ADDQ $32, SP
RET
請(qǐng)注意,這段代碼不是完全相同的輸出,但我對(duì)其進(jìn)行了一些修改以使其更加清晰。引用的變量是堆棧位置。
我的結(jié)論是,雖然 Go 編譯器確實(shí)采用了一些優(yōu)化技術(shù)來生成更高性能的代碼(請(qǐng)參閱編譯器優(yōu)化),但它在分配 CPU 寄存器方面做得不是很好(與 C 編譯器生成的相比),并且依賴于堆棧太多,尤其是對(duì)于返回值——我認(rèn)為必須有一個(gè)可能與語言工作方式相關(guān)的原因(例如多個(gè)返回值)。
更新 1
只是為了比較,這是 GCC (amd64) 為相同功能生成的機(jī)器碼:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
# Do the comparison
movq %rdi, %rbx
cmpq $2, %rbx
jge @ELSE
# Save "c" in "r"
movq %rbx, %rax
jmp @RETURN
@ELSE:
# Compute fib(i - 2)
leaq -2(%rbx), %rdi
callq fibonacci
# Compute fib(i - 1)
movq %rax, %r14
decq %rbx
movq %rbx, %rdi
callq fibonacci
# Add previous results together
addq %r14, %rax
@RETURN:
popq %rbx
popq %r14
popq %rbp
retq
更新 2
話雖如此,我堅(jiān)信在實(shí)際項(xiàng)目中,語言運(yùn)行時(shí)(例如對(duì)象分配、垃圾收集、調(diào)用間接、動(dòng)態(tài)加載、并發(fā)支持等)會(huì)對(duì)程序的整體性能產(chǎn)生更大的影響,而不是功能級(jí)別的微優(yōu)化。
- 1 回答
- 0 關(guān)注
- 188 瀏覽
添加回答
舉報(bào)