From: Cherry Mui Date: Fri, 4 Nov 2022 00:56:21 +0000 (-0400) Subject: cmd/compile/internal/pgo: use slices for in/out edges X-Git-Tag: go1.20rc1~416 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7e88b866f9576d6f9ddfe0a054da7383bfff54fa;p=gostls13.git cmd/compile/internal/pgo: use slices for in/out edges Currently in the pprof Graph, a Node's in/out edges are represented as maps, keyed by the source/destination Nodes. For a Node it usually has a very small number of edges, so linear search would be generally faster than map operations. Use slices and linear search instead. Change-Id: I5ab06be0c019373cd3a845b9f3282731372e9c4c Reviewed-on: https://go-review.googlesource.com/c/go/+/447802 Reviewed-by: Michael Pratt Run-TryBot: Cherry Mui TryBot-Result: Gopher Robot --- diff --git a/src/cmd/compile/internal/pgo/graph.go b/src/cmd/compile/internal/pgo/graph.go index fd2dac544e..193100897d 100644 --- a/src/cmd/compile/internal/pgo/graph.go +++ b/src/cmd/compile/internal/pgo/graph.go @@ -94,11 +94,7 @@ func (n *Node) AddToEdge(to *Node, v int64, residual, inline bool) { // AddToEdgeDiv increases the weight of an edge between two nodes. If // there isn't such an edge one is created. func (n *Node) AddToEdgeDiv(to *Node, dv, v int64, residual, inline bool) { - if n.Out[to] != to.In[n] { - panic(fmt.Errorf("asymmetric edges %v %v", *n, *to)) - } - - if e := n.Out[to]; e != nil { + if e := n.Out.FindTo(to); e != nil { e.WeightDiv += dv e.Weight += v if residual { @@ -111,8 +107,8 @@ func (n *Node) AddToEdgeDiv(to *Node, dv, v int64, residual, inline bool) { } info := &Edge{Src: n, Dest: to, WeightDiv: dv, Weight: v, Residual: residual, Inline: inline} - n.Out[to] = info - to.In[n] = info + n.Out.Add(info) + to.In.Add(info) } // NodeInfo contains the attributes for a node. @@ -186,8 +182,6 @@ func (nm NodeMap) FindOrInsertNode(info NodeInfo, kept NodeSet) *Node { n := &Node{ Info: info, - In: make(EdgeMap), - Out: make(EdgeMap), } nm[info] = n if info.Address == 0 && info.Lineno == 0 { @@ -204,7 +198,30 @@ func (nm NodeMap) FindOrInsertNode(info NodeInfo, kept NodeSet) *Node { } // EdgeMap is used to represent the incoming/outgoing edges from a node. -type EdgeMap map[*Node]*Edge +type EdgeMap []*Edge + +func (em EdgeMap) FindTo(n *Node) *Edge { + for _, e := range em { + if e.Dest == n { + return e + } + } + return nil +} + +func (em *EdgeMap) Add(e *Edge) { + *em = append(*em, e) +} + +func (em *EdgeMap) Delete(e *Edge) { + for i, edge := range *em { + if edge == e { + (*em)[i] = (*em)[len(*em)-1] + *em = (*em)[:len(*em)-1] + return + } + } +} // Edge contains any attributes to be represented about edges in a graph. type Edge struct { @@ -513,10 +530,10 @@ func getNodesAboveCumCutoff(nodes Nodes, nodeCutoff int64) Nodes { func (g *Graph) TrimLowFrequencyEdges(edgeCutoff int64) int { var droppedEdges int for _, n := range g.Nodes { - for src, e := range n.In { + for _, e := range n.In { if abs64(e.Weight) < edgeCutoff { - delete(n.In, src) - delete(src.Out, n) + n.In.Delete(e) + e.Src.Out.Delete(e) droppedEdges++ } }