Skip to content

Commit

Permalink
optimisation: pre-allocate, and fewer slices during summarisation
Browse files Browse the repository at this point in the history
Pre-allocating slices really pays dividends when we create loads of
them and they don't grow very large.

We take special care to return nil rather than 0-length slices. This
a) saves further on allocation, and b) is required for some crude
tests to pass that match on nil rather than length.

Also, a bunch of code in templates/tables used slices as Maybe's,
i.e. returning nil or a single-element slice, which is horrendously
inefficient. Eliminating these saves a lot of allocations.
  • Loading branch information
rade committed Dec 25, 2017
1 parent 78b9ac3 commit 3de0468
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 15 deletions.
9 changes: 8 additions & 1 deletion render/detailed/parents.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ var (

// Parents renders the parents of this report.Node, which have been aggregated
// from the probe reports.
func Parents(r report.Report, n report.Node) (result []Parent) {
func Parents(r report.Report, n report.Node) []Parent {
if n.Parents.Size() == 0 {
return nil
}
result := make([]Parent, 0, n.Parents.Size())
topologyIDs := []string{}
for topologyID := range getLabelForTopology {
topologyIDs = append(topologyIDs, topologyID)
Expand Down Expand Up @@ -80,6 +84,9 @@ func Parents(r report.Report, n report.Node) (result []Parent) {
})
}
}
if len(result) == 0 {
return nil
}
return result
}

Expand Down
22 changes: 15 additions & 7 deletions report/metadata_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type MetadataTemplate struct {
From string `json:"from,omitempty"` // Defines how to get the value from a report node
}

// MetadataRows returns the rows for a node
func (t MetadataTemplate) MetadataRows(n Node) []MetadataRow {
// MetadataRow returns the row for a node
func (t MetadataTemplate) MetadataRow(n Node) (MetadataRow, bool) {
from := fromDefault
switch t.From {
case FromLatest:
Expand All @@ -40,16 +40,16 @@ func (t MetadataTemplate) MetadataRows(n Node) []MetadataRow {
from = fromCounters
}
if val, ok := from(n, t.ID); ok {
return []MetadataRow{{
return MetadataRow{
ID: t.ID,
Label: t.Label,
Value: val,
Truncate: t.Truncate,
Datatype: t.Datatype,
Priority: t.Priority,
}}
}, true
}
return nil
return MetadataRow{}, false
}

func fromDefault(n Node, key string) (string, bool) {
Expand Down Expand Up @@ -90,9 +90,17 @@ type MetadataTemplates map[string]MetadataTemplate

// MetadataRows returns the rows for a node
func (e MetadataTemplates) MetadataRows(n Node) []MetadataRow {
var rows []MetadataRow
if len(e) == 0 {
return nil
}
rows := make([]MetadataRow, 0, len(e))
for _, template := range e {
rows = append(rows, template.MetadataRows(n)...)
if row, ok := template.MetadataRow(n); ok {
rows = append(rows, row)
}
}
if len(rows) == 0 {
return nil
}
sort.Sort(MetadataRowsByPriority(rows))
return rows
Expand Down
20 changes: 14 additions & 6 deletions report/metric_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ type MetricTemplate struct {
Priority float64 `json:"priority,omitempty"`
}

// MetricRows returns the rows for a node
func (t MetricTemplate) MetricRows(n Node) []MetricRow {
// MetricRow returns the row for a node
func (t MetricTemplate) MetricRow(n Node) (MetricRow, bool) {
metric, ok := n.Metrics.Lookup(t.ID)
if !ok {
return nil
return MetricRow{}, false
}
row := MetricRow{
ID: t.ID,
Expand All @@ -31,17 +31,25 @@ func (t MetricTemplate) MetricRows(n Node) []MetricRow {
if s, ok := metric.LastSample(); ok {
row.Value = toFixed(s.Value, 2)
}
return []MetricRow{row}
return row, true
}

// MetricTemplates is a mergeable set of metric templates
type MetricTemplates map[string]MetricTemplate

// MetricRows returns the rows for a node
func (e MetricTemplates) MetricRows(n Node) []MetricRow {
var rows []MetricRow
if len(e) == 0 {
return nil
}
rows := make([]MetricRow, 0, len(e))
for _, template := range e {
rows = append(rows, template.MetricRows(n)...)
if row, ok := template.MetricRow(n); ok {
rows = append(rows, row)
}
}
if len(rows) == 0 {
return nil
}
sort.Sort(MetricRowsByPriority(rows))
return rows
Expand Down
5 changes: 4 additions & 1 deletion report/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,10 @@ type TableTemplates map[string]TableTemplate

// Tables renders the TableTemplates for a given node.
func (t TableTemplates) Tables(node Node) []Table {
var result []Table
if len(t) == 0 {
return nil
}
result := make([]Table, 0, len(t))
for _, template := range t {
rows, truncationCount := node.ExtractTable(template)
// Extract the type from the template; default to
Expand Down

0 comments on commit 3de0468

Please sign in to comment.