Browse Source

Factor out common percentage formatting code. (#265)

Alexey Alexandrov 7 years ago
parent
commit
749be1c0d9
No account linked to committer's email address

+ 2
- 19
internal/graph/dotgraph.go View File

154
 	if flat != 0 {
154
 	if flat != 0 {
155
 		label = label + fmt.Sprintf(`%s (%s)`,
155
 		label = label + fmt.Sprintf(`%s (%s)`,
156
 			flatValue,
156
 			flatValue,
157
-			strings.TrimSpace(percentage(flat, b.config.Total)))
157
+			strings.TrimSpace(measurement.Percentage(flat, b.config.Total)))
158
 	} else {
158
 	} else {
159
 		label = label + "0"
159
 		label = label + "0"
160
 	}
160
 	}
168
 		cumValue = b.config.FormatValue(cum)
168
 		cumValue = b.config.FormatValue(cum)
169
 		label = label + fmt.Sprintf(`of %s (%s)`,
169
 		label = label + fmt.Sprintf(`of %s (%s)`,
170
 			cumValue,
170
 			cumValue,
171
-			strings.TrimSpace(percentage(cum, b.config.Total)))
171
+			strings.TrimSpace(measurement.Percentage(cum, b.config.Total)))
172
 	}
172
 	}
173
 
173
 
174
 	// Scale font sizes from 8 to 24 based on percentage of flat frequency.
174
 	// Scale font sizes from 8 to 24 based on percentage of flat frequency.
380
 	return fmt.Sprintf("#%02x%02x%02x", uint8(r*255.0), uint8(g*255.0), uint8(b*255.0))
380
 	return fmt.Sprintf("#%02x%02x%02x", uint8(r*255.0), uint8(g*255.0), uint8(b*255.0))
381
 }
381
 }
382
 
382
 
383
-// percentage computes the percentage of total of a value, and encodes
384
-// it as a string. At least two digits of precision are printed.
385
-func percentage(value, total int64) string {
386
-	var ratio float64
387
-	if total != 0 {
388
-		ratio = math.Abs(float64(value)/float64(total)) * 100
389
-	}
390
-	switch {
391
-	case math.Abs(ratio) >= 99.95 && math.Abs(ratio) <= 100.05:
392
-		return "  100%"
393
-	case math.Abs(ratio) >= 1.0:
394
-		return fmt.Sprintf("%5.2f%%", ratio)
395
-	default:
396
-		return fmt.Sprintf("%5.2g%%", ratio)
397
-	}
398
-}
399
-
400
 func multilinePrintableName(info *NodeInfo) string {
383
 func multilinePrintableName(info *NodeInfo) string {
401
 	infoCopy := *info
384
 	infoCopy := *info
402
 	infoCopy.Name = strings.Replace(infoCopy.Name, "::", `\n`, -1)
385
 	infoCopy.Name = strings.Replace(infoCopy.Name, "::", `\n`, -1)

+ 18
- 0
internal/measurement/measurement.go View File

17
 
17
 
18
 import (
18
 import (
19
 	"fmt"
19
 	"fmt"
20
+	"math"
20
 	"strings"
21
 	"strings"
21
 	"time"
22
 	"time"
22
 
23
 
154
 	return sv + u
155
 	return sv + u
155
 }
156
 }
156
 
157
 
158
+// Percentage computes the percentage of total of a value, and encodes
159
+// it as a string. At least two digits of precision are printed.
160
+func Percentage(value, total int64) string {
161
+	var ratio float64
162
+	if total != 0 {
163
+		ratio = math.Abs(float64(value)/float64(total)) * 100
164
+	}
165
+	switch {
166
+	case math.Abs(ratio) >= 99.95 && math.Abs(ratio) <= 100.05:
167
+		return "  100%"
168
+	case math.Abs(ratio) >= 1.0:
169
+		return fmt.Sprintf("%5.2f%%", ratio)
170
+	default:
171
+		return fmt.Sprintf("%5.2g%%", ratio)
172
+	}
173
+}
174
+
157
 // isMemoryUnit returns whether a name is recognized as a memory size
175
 // isMemoryUnit returns whether a name is recognized as a memory size
158
 // unit.
176
 // unit.
159
 func isMemoryUnit(unit string) bool {
177
 func isMemoryUnit(unit string) bool {

+ 12
- 30
internal/report/report.go View File

19
 import (
19
 import (
20
 	"fmt"
20
 	"fmt"
21
 	"io"
21
 	"io"
22
-	"math"
23
 	"path/filepath"
22
 	"path/filepath"
24
 	"regexp"
23
 	"regexp"
25
 	"sort"
24
 	"sort"
425
 		}
424
 		}
426
 		fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
425
 		fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
427
 			rpt.formatValue(flatSum), rpt.formatValue(cumSum),
426
 			rpt.formatValue(flatSum), rpt.formatValue(cumSum),
428
-			percentage(cumSum, rpt.total))
427
+			measurement.Percentage(cumSum, rpt.total))
429
 
428
 
430
 		function, file, line := "", "", 0
429
 		function, file, line := "", "", 0
431
 		for _, n := range ns {
430
 		for _, n := range ns {
704
 		for _, t := range graph.SortTags(tags, true) {
703
 		for _, t := range graph.SortTags(tags, true) {
705
 			f, u := measurement.Scale(t.FlatValue(), o.SampleUnit, o.OutputUnit)
704
 			f, u := measurement.Scale(t.FlatValue(), o.SampleUnit, o.OutputUnit)
706
 			if total > 0 {
705
 			if total > 0 {
707
-				fmt.Fprintf(tabw, " \t%.1f%s (%s):\t %s\n", f, u, percentage(t.FlatValue(), total), t.Name)
706
+				fmt.Fprintf(tabw, " \t%.1f%s (%s):\t %s\n", f, u, measurement.Percentage(t.FlatValue(), total), t.Name)
708
 			} else {
707
 			} else {
709
 				fmt.Fprintf(tabw, " \t%.1f%s:\t %s\n", f, u, t.Name)
708
 				fmt.Fprintf(tabw, " \t%.1f%s:\t %s\n", f, u, t.Name)
710
 			}
709
 			}
789
 		}
788
 		}
790
 		flatSum += item.Flat
789
 		flatSum += item.Flat
791
 		fmt.Fprintf(w, "%10s %s %s %10s %s  %s%s\n",
790
 		fmt.Fprintf(w, "%10s %s %s %10s %s  %s%s\n",
792
-			item.FlatFormat, percentage(item.Flat, rpt.total),
793
-			percentage(flatSum, rpt.total),
794
-			item.CumFormat, percentage(item.Cum, rpt.total),
791
+			item.FlatFormat, measurement.Percentage(item.Flat, rpt.total),
792
+			measurement.Percentage(flatSum, rpt.total),
793
+			item.CumFormat, measurement.Percentage(item.Cum, rpt.total),
795
 			item.Name, inl)
794
 			item.Name, inl)
796
 	}
795
 	}
797
 	return nil
796
 	return nil
1030
 				inline = " (inline)"
1029
 				inline = " (inline)"
1031
 			}
1030
 			}
1032
 			fmt.Fprintf(w, "%50s %s |   %s%s\n", rpt.formatValue(in.Weight),
1031
 			fmt.Fprintf(w, "%50s %s |   %s%s\n", rpt.formatValue(in.Weight),
1033
-				percentage(in.Weight, cum), in.Src.Info.PrintableName(), inline)
1032
+				measurement.Percentage(in.Weight, cum), in.Src.Info.PrintableName(), inline)
1034
 		}
1033
 		}
1035
 
1034
 
1036
 		// Print current node.
1035
 		// Print current node.
1037
 		flatSum += flat
1036
 		flatSum += flat
1038
 		fmt.Fprintf(w, "%10s %s %s %10s %s                | %s\n",
1037
 		fmt.Fprintf(w, "%10s %s %s %10s %s                | %s\n",
1039
 			rpt.formatValue(flat),
1038
 			rpt.formatValue(flat),
1040
-			percentage(flat, rpt.total),
1041
-			percentage(flatSum, rpt.total),
1039
+			measurement.Percentage(flat, rpt.total),
1040
+			measurement.Percentage(flatSum, rpt.total),
1042
 			rpt.formatValue(cum),
1041
 			rpt.formatValue(cum),
1043
-			percentage(cum, rpt.total),
1042
+			measurement.Percentage(cum, rpt.total),
1044
 			name)
1043
 			name)
1045
 
1044
 
1046
 		// Print outgoing edges.
1045
 		// Print outgoing edges.
1051
 				inline = " (inline)"
1050
 				inline = " (inline)"
1052
 			}
1051
 			}
1053
 			fmt.Fprintf(w, "%50s %s |   %s%s\n", rpt.formatValue(out.Weight),
1052
 			fmt.Fprintf(w, "%50s %s |   %s%s\n", rpt.formatValue(out.Weight),
1054
-				percentage(out.Weight, cum), out.Dest.Info.PrintableName(), inline)
1053
+				measurement.Percentage(out.Weight, cum), out.Dest.Info.PrintableName(), inline)
1055
 		}
1054
 		}
1056
 	}
1055
 	}
1057
 	if len(g.Nodes) > 0 {
1056
 	if len(g.Nodes) > 0 {
1083
 	return nil
1082
 	return nil
1084
 }
1083
 }
1085
 
1084
 
1086
-// percentage computes the percentage of total of a value, and encodes
1087
-// it as a string. At least two digits of precision are printed.
1088
-func percentage(value, total int64) string {
1089
-	var ratio float64
1090
-	if total != 0 {
1091
-		ratio = math.Abs(float64(value)/float64(total)) * 100
1092
-	}
1093
-	switch {
1094
-	case math.Abs(ratio) >= 99.95 && math.Abs(ratio) <= 100.05:
1095
-		return "  100%"
1096
-	case math.Abs(ratio) >= 1.0:
1097
-		return fmt.Sprintf("%5.2f%%", ratio)
1098
-	default:
1099
-		return fmt.Sprintf("%5.2g%%", ratio)
1100
-	}
1101
-}
1102
-
1103
 // ProfileLabels returns printable labels for a profile.
1085
 // ProfileLabels returns printable labels for a profile.
1104
 func ProfileLabels(rpt *Report) []string {
1086
 func ProfileLabels(rpt *Report) []string {
1105
 	label := []string{}
1087
 	label := []string{}
1131
 		totalNanos, totalUnit := measurement.Scale(rpt.total, o.SampleUnit, "nanoseconds")
1113
 		totalNanos, totalUnit := measurement.Scale(rpt.total, o.SampleUnit, "nanoseconds")
1132
 		var ratio string
1114
 		var ratio string
1133
 		if totalUnit == "ns" && totalNanos != 0 {
1115
 		if totalUnit == "ns" && totalNanos != 0 {
1134
-			ratio = "(" + percentage(int64(totalNanos), prof.DurationNanos) + ")"
1116
+			ratio = "(" + measurement.Percentage(int64(totalNanos), prof.DurationNanos) + ")"
1135
 		}
1117
 		}
1136
 		label = append(label, fmt.Sprintf("Duration: %s, Total samples = %s %s", duration, rpt.formatValue(rpt.total), ratio))
1118
 		label = append(label, fmt.Sprintf("Duration: %s, Total samples = %s %s", duration, rpt.formatValue(rpt.total), ratio))
1137
 	}
1119
 	}
1162
 		label = append(label, activeFilters...)
1144
 		label = append(label, activeFilters...)
1163
 	}
1145
 	}
1164
 
1146
 
1165
-	label = append(label, fmt.Sprintf("Showing nodes accounting for %s, %s of %s total", rpt.formatValue(flatSum), strings.TrimSpace(percentage(flatSum, rpt.total)), rpt.formatValue(rpt.total)))
1147
+	label = append(label, fmt.Sprintf("Showing nodes accounting for %s, %s of %s total", rpt.formatValue(flatSum), strings.TrimSpace(measurement.Percentage(flatSum, rpt.total)), rpt.formatValue(rpt.total)))
1166
 
1148
 
1167
 	if rpt.total != 0 {
1149
 	if rpt.total != 0 {
1168
 		if droppedNodes > 0 {
1150
 		if droppedNodes > 0 {

+ 3
- 2
internal/report/source.go View File

28
 	"strings"
28
 	"strings"
29
 
29
 
30
 	"github.com/google/pprof/internal/graph"
30
 	"github.com/google/pprof/internal/graph"
31
+	"github.com/google/pprof/internal/measurement"
31
 	"github.com/google/pprof/internal/plugin"
32
 	"github.com/google/pprof/internal/plugin"
32
 )
33
 )
33
 
34
 
99
 			fmt.Fprintf(w, "ROUTINE ======================== %s in %s\n", name, filename)
100
 			fmt.Fprintf(w, "ROUTINE ======================== %s in %s\n", name, filename)
100
 			fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
101
 			fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
101
 				rpt.formatValue(flatSum), rpt.formatValue(cumSum),
102
 				rpt.formatValue(flatSum), rpt.formatValue(cumSum),
102
-				percentage(cumSum, rpt.total))
103
+				measurement.Percentage(cumSum, rpt.total))
103
 
104
 
104
 			if err != nil {
105
 			if err != nil {
105
 				fmt.Fprintf(w, " Error: %v\n", err)
106
 				fmt.Fprintf(w, " Error: %v\n", err)
343
 `,
344
 `,
344
 		template.HTMLEscapeString(name), template.HTMLEscapeString(path),
345
 		template.HTMLEscapeString(name), template.HTMLEscapeString(path),
345
 		rpt.formatValue(flatSum), rpt.formatValue(cumSum),
346
 		rpt.formatValue(flatSum), rpt.formatValue(cumSum),
346
-		percentage(cumSum, rpt.total))
347
+		measurement.Percentage(cumSum, rpt.total))
347
 }
348
 }
348
 
349
 
349
 // printFunctionSourceLine prints a source line and the corresponding assembly.
350
 // printFunctionSourceLine prints a source line and the corresponding assembly.