Skip to content

Commit 82ee768

Browse files
authored
Merge pull request #5079 from chlunde/perf-1
perf: improve applyOrdering by avoid call to GetByCurrentId
2 parents 116b307 + 5c7f8b8 commit 82ee768

File tree

2 files changed

+44
-62
lines changed

2 files changed

+44
-62
lines changed

api/internal/builtins/SortOrderTransformer.go

Lines changed: 22 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/builtin/sortordertransformer/SortOrderTransformer.go

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -77,34 +77,16 @@ func (p *plugin) Transform(m resmap.ResMap) (err error) {
7777

7878
// Sort
7979
if p.SortOptions.Order == types.LegacySortOrder {
80-
s := newLegacyIDSorter(m.AllIds(), p.SortOptions.LegacySortOptions)
80+
s := newLegacyIDSorter(m.Resources(), p.SortOptions.LegacySortOptions)
8181
sort.Sort(s)
82-
err = applyOrdering(m, s.resids)
83-
if err != nil {
84-
return err
85-
}
86-
}
87-
return nil
88-
}
8982

90-
// applyOrdering takes resources (given in ResMap) and a desired ordering given
91-
// as a sequence of ResIds, and updates the ResMap's resources to match the
92-
// ordering.
93-
func applyOrdering(m resmap.ResMap, ordering []resid.ResId) error {
94-
var err error
95-
resources := make([]*resource.Resource, m.Size())
96-
// Clear and refill with the correct order
97-
for i, id := range ordering {
98-
resources[i], err = m.GetByCurrentId(id)
99-
if err != nil {
100-
return errors.WrapPrefixf(err, "expected match for sorting")
101-
}
102-
}
103-
m.Clear()
104-
for _, r := range resources {
105-
err = m.Append(r)
106-
if err != nil {
107-
return errors.WrapPrefixf(err, "SortOrderTransformer: Failed to append to resources")
83+
// Clear the map and re-add the resources in the sorted order.
84+
m.Clear()
85+
for _, r := range s.resources {
86+
err := m.Append(r)
87+
if err != nil {
88+
return errors.WrapPrefixf(err, "SortOrderTransformer: Failed to append to resources")
89+
}
10890
}
10991
}
11092
return nil
@@ -120,12 +102,17 @@ func applyOrdering(m resmap.ResMap, ordering []resid.ResId) error {
120102
type legacyIDSorter struct {
121103
// resids only stores the metadata of the object. This is an optimization as
122104
// it's expensive to compute these again and again during ordering.
123-
resids []resid.ResId
105+
resids []resid.ResId
106+
// Initially, we sorted the metadata (ResId) of each object and then called GetByCurrentId on each to construct the final list.
107+
// The problem is that GetByCurrentId is inefficient and does a linear scan in a list every time we do that.
108+
// So instead, we sort resources alongside the ResIds.
109+
resources []*resource.Resource
110+
124111
typeOrders map[string]int
125112
}
126113

127114
func newLegacyIDSorter(
128-
resids []resid.ResId,
115+
resources []*resource.Resource,
129116
options *types.LegacySortOptions) *legacyIDSorter {
130117
// Precalculate a resource ranking based on the priority lists.
131118
var typeOrders = func() map[string]int {
@@ -138,17 +125,21 @@ func newLegacyIDSorter(
138125
}
139126
return m
140127
}()
141-
return &legacyIDSorter{
142-
resids: resids,
143-
typeOrders: typeOrders,
128+
129+
ret := &legacyIDSorter{typeOrders: typeOrders}
130+
for _, res := range resources {
131+
ret.resids = append(ret.resids, res.CurId())
132+
ret.resources = append(ret.resources, res)
144133
}
134+
return ret
145135
}
146136

147137
var _ sort.Interface = legacyIDSorter{}
148138

149139
func (a legacyIDSorter) Len() int { return len(a.resids) }
150140
func (a legacyIDSorter) Swap(i, j int) {
151141
a.resids[i], a.resids[j] = a.resids[j], a.resids[i]
142+
a.resources[i], a.resources[j] = a.resources[j], a.resources[i]
152143
}
153144
func (a legacyIDSorter) Less(i, j int) bool {
154145
if !a.resids[i].Gvk.Equals(a.resids[j].Gvk) {

0 commit comments

Comments
 (0)