作者:迷失刀 | 来源:互联网 | 2022-12-03 09:57
我注意到以下两个map[int]int
变量增量方法的3倍速度因子:
快速: myMap[key]++
慢: myMap[key]=myMap[key]+1
这可能并不奇怪,因为,至少天真地,在第二种情况下,我指示Go两次访问myMap.我只是很好奇:熟悉Go编译器的人能帮助我理解这些操作在地图上的区别吗?有了编译器如何工作的知识,是否有更快的技巧来增加地图?
编辑:在本地运行差异不太明显,但仍然存在:
package main
import (
"fmt"
"math"
"time"
)
func main() {
x, y := make(map[int]int), make(map[int]int)
x[0], y[0] = 0, 0
steps := int(math.Pow(10, 9))
start1 := time.Now()
for i := 0; i
输出:
++ took 8.1739809s
y=y+1 took 17.9079386s
Edit2:正如我所建议的那样,我抛弃了机器代码.以下是相关的片段
对于x [0] ++
0x4981e3 488d05b6830100 LEAQ runtime.types+95648(SB), AX
0x4981ea 48890424 MOVQ AX, 0(SP)
0x4981ee 488d8c2400020000 LEAQ 0x200(SP), CX
0x4981f6 48894c2408 MOVQ CX, 0x8(SP)
0x4981fb 48c744241000000000 MOVQ $0x0, 0x10(SP)
0x498204 e8976df7ff CALL runtime.mapassign_fast64(SB)
0x498209 488b442418 MOVQ 0x18(SP), AX
0x49820e 48ff00 INCQ 0(AX)
对于y [0] = y [0] + 1
0x498302 488d0597820100 LEAQ runtime.types+95648(SB), AX
0x498309 48890424 MOVQ AX, 0(SP)
0x49830d 488d8c24d0010000 LEAQ 0x1d0(SP), CX
0x498315 48894c2408 MOVQ CX, 0x8(SP)
0x49831a 48c744241000000000 MOVQ $0x0, 0x10(SP)
0x498323 e80869f7ff CALL runtime.mapaccess1_fast64(SB)
0x498328 488b442418 MOVQ 0x18(SP), AX
0x49832d 488b00 MOVQ 0(AX), AX
0x498330 4889442448 MOVQ AX, 0x48(SP)
0x498335 488d0d64820100 LEAQ runtime.types+95648(SB), CX
0x49833c 48890c24 MOVQ CX, 0(SP)
0x498340 488d9424d0010000 LEAQ 0x1d0(SP), DX
0x498348 4889542408 MOVQ DX, 0x8(SP)
0x49834d 48c744241000000000 MOVQ $0x0, 0x10(SP)
0x498356 e8456cf7ff CALL runtime.mapassign_fast64(SB)
0x49835b 488b442418 MOVQ 0x18(SP), AX
0x498360 488b4c2448 MOVQ 0x48(SP), CX
0x498365 48ffc1 INCQ CX
0x498368 488908 MOVQ CX, 0(AX)
奇怪的是,++甚至没有调用地图访问!++显然是一个更简单的操作,按2或3的顺序.我解析机器的能力就此结束,所以如果有人能够洞察正在发生的事情,我很乐意听到它