mirror of
https://github.com/golang/go
synced 2024-11-24 06:30:22 -07:00
cmd/link: use string map for symbols with single version
Reduces link time by ~3% Results with gc on: name old s/op new s/op delta LinkCmdGo 0.82 ± 2% 0.78 ± 2% -3.90% (p=0.000 n=17+17) LinkJuju 7.11 ± 7% 6.87 ± 6% -3.41% (p=0.012 n=20+19) Less noisy results with gc turned off: name old s/op new s/op delta LinkCmdGo 0.66 ± 2% 0.64 ± 2% -3.14% (p=0.000 n=18+20) LinkJuju 5.91 ± 1% 5.72 ± 2% -3.17% (p=0.000 n=20+20) Change-Id: I4cac7933b0b22d0aee18255e1ab54550ad364593 Reviewed-on: https://go-review.googlesource.com/20478 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: David Crawshaw <crawshaw@golang.org> Run-TryBot: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
bb48b864b1
commit
eb57a1dd75
@ -161,17 +161,23 @@ type Shlib struct {
|
||||
}
|
||||
|
||||
type Link struct {
|
||||
Thechar int32
|
||||
Thestring string
|
||||
Goarm int32
|
||||
Headtype int
|
||||
Arch *LinkArch
|
||||
Debugasm int32
|
||||
Debugvlog int32
|
||||
Bso *obj.Biobuf
|
||||
Windows int32
|
||||
Goroot string
|
||||
Hash map[symVer]*LSym
|
||||
Thechar int32
|
||||
Thestring string
|
||||
Goarm int32
|
||||
Headtype int
|
||||
Arch *LinkArch
|
||||
Debugasm int32
|
||||
Debugvlog int32
|
||||
Bso *obj.Biobuf
|
||||
Windows int32
|
||||
Goroot string
|
||||
|
||||
// Map for fast access of symbols based on name.
|
||||
HashName map[string]*LSym
|
||||
// Fallback map based also on version, for symbols
|
||||
// with more than one version (see func _lookup).
|
||||
HashVersion map[symVer]*LSym
|
||||
|
||||
Allsym []*LSym
|
||||
Nsymbol int32
|
||||
Tlsg *LSym
|
||||
|
@ -58,11 +58,12 @@ var headers = []struct {
|
||||
|
||||
func linknew(arch *LinkArch) *Link {
|
||||
ctxt := &Link{
|
||||
Hash: make(map[symVer]*LSym, 100000), // preallocate about 2mb for hash
|
||||
Allsym: make([]*LSym, 0, 100000),
|
||||
Arch: arch,
|
||||
Version: obj.HistVersion,
|
||||
Goroot: obj.Getgoroot(),
|
||||
HashName: make(map[string]*LSym, 100000), // preallocate about 2mb for hash
|
||||
HashVersion: make(map[symVer]*LSym),
|
||||
Allsym: make([]*LSym, 0, 100000),
|
||||
Arch: arch,
|
||||
Version: obj.HistVersion,
|
||||
Goroot: obj.Getgoroot(),
|
||||
}
|
||||
|
||||
p := obj.Getgoarch()
|
||||
@ -182,9 +183,20 @@ type symVer struct {
|
||||
}
|
||||
|
||||
func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
|
||||
s := ctxt.Hash[symVer{symb, v}]
|
||||
// Most symbols have only a single version, and a string key
|
||||
// is faster to search for. So we store the first symbol in HashName,
|
||||
// keyed only by symbol name. If there are name collisions, the
|
||||
// alternate versions are stored in the spill over map
|
||||
// HashVersion.
|
||||
s, exist := ctxt.HashName[symb]
|
||||
if s != nil {
|
||||
return s
|
||||
if int(s.Version) == v {
|
||||
return s
|
||||
}
|
||||
s = ctxt.HashVersion[symVer{symb, v}]
|
||||
if s != nil {
|
||||
return s
|
||||
}
|
||||
}
|
||||
if creat == 0 {
|
||||
return nil
|
||||
@ -192,7 +204,11 @@ func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
|
||||
|
||||
s = linknewsym(ctxt, symb, v)
|
||||
s.Extname = s.Name
|
||||
ctxt.Hash[symVer{symb, v}] = s
|
||||
if exist {
|
||||
ctxt.HashVersion[symVer{symb, v}] = s
|
||||
} else {
|
||||
ctxt.HashName[symb] = s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user