Skip to content

Commit f76137d

Browse files
committed
update map
1 parent c2c4645 commit f76137d

File tree

1 file changed

+96
-4
lines changed

1 file changed

+96
-4
lines changed

map.md

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,14 +759,106 @@ func advanceEvacuationMark(h *hmap, t *maptype, newbit uintptr) {
759759

760760
我们可以用 lldb 来进行简单验证:
761761

762-
```
762+
```go
763+
package main
764+
765+
import "fmt"
766+
767+
func main() {
768+
type P struct {
769+
Age [17]int
770+
}
771+
var a = map[P]int{}
772+
a[P{}] = 1
773+
fmt.Println(a)
774+
}
775+
776+
763777
```
764778

779+
在 lldb 中可以看到 indirectkey 为 false。
780+
781+
```shell
782+
(lldb) b mapassign
783+
(lldb) p *t
784+
(runtime.maptype) *t = {
785+
typ = {
786+
size = 0x0000000000000008
787+
ptrdata = 0x0000000000000008
788+
hash = 2678392653
789+
tflag = 2
790+
align = 8
791+
fieldalign = 8
792+
kind = 53
793+
alg = 0x0000000001137020
794+
gcdata = 0x00000000010cf298
795+
str = 26128
796+
ptrToThis = 0
797+
}
798+
key = 0x00000000010a77a0
799+
elem = 0x000000000109d180
800+
bucket = 0x00000000010aea00
801+
hmap = 0x00000000010b4da0
802+
keysize = 128 =======> 128 字节
803+
indirectkey = false =====> false
804+
valuesize = 8
805+
indirectvalue = false
806+
bucketsize = 1104
807+
reflexivekey = true
808+
needkeyupdate = false
809+
}
765810
```
811+
812+
给 P 加一个字节:
813+
814+
```go
815+
package main
816+
817+
import "fmt"
818+
819+
func main() {
820+
type P struct {
821+
Age [16]int
822+
Male bool
823+
}
824+
var a = map[P]int{}
825+
a[P{}] = 1
826+
fmt.Println(a)
827+
}
766828
```
767829

768-
## 其它
830+
indirectkey 变成了 true:
831+
832+
```shell
833+
(lldb) p *t
834+
(runtime.maptype) *t = {
835+
typ = {
836+
size = 0x0000000000000008
837+
ptrdata = 0x0000000000000008
838+
hash = 2678392653
839+
tflag = 2
840+
align = 8
841+
fieldalign = 8
842+
kind = 53
843+
alg = 0x0000000001137020
844+
gcdata = 0x00000000010cf3b8
845+
str = 26176
846+
ptrToThis = 0
847+
}
848+
key = 0x00000000010a92c0
849+
elem = 0x000000000109d280
850+
bucket = 0x00000000010aeb20
851+
hmap = 0x00000000010b4ec0
852+
keysize = 8
853+
indirectkey = true
854+
valuesize = 8
855+
indirectvalue = false
856+
bucketsize = 144
857+
reflexivekey = true
858+
needkeyupdate = false
859+
}
860+
```
769861

770-
针对 32 位、64 位 和 string 类型的 map 元素的访问、赋值、删除、扩容,Go 内部有都有对应的优化函数,比如 mapaccess1 对应有 mapaccess1_fast64,mapaccess1_fast32,mapaccess1_faststr。mapassign 对应有 mapassign_fast64,mapassign_fast32 和 mapassign_faststr
862+
indirectvalue 也是完全一样的,超过 128 字节(不含)时,会被赋值为 true,并退化为指针
771863

772-
但这些优化函数长得都差不多,不知为何官方没有用脚本来做这些优化函数的生成工作。可见有时候 Go team 的复制粘贴功力也是蛮强的。
864+
## 总结

0 commit comments

Comments
 (0)