]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/pgo: use slices for in/out edges
authorCherry Mui <cherryyz@google.com>
Fri, 4 Nov 2022 00:56:21 +0000 (20:56 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 4 Nov 2022 20:37:38 +0000 (20:37 +0000)
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 <mpratt@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/pgo/graph.go

index fd2dac544e8ea7353fb2bbbfd564fd44da7efd97..193100897d11903f5df89143cd50e7bbf80a3d59 100644 (file)
@@ -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++
                        }
                }