Improve performance of simple reflist merges

When merging reflists with ignoreConflicting set to true and
overrideMatching set to false, the individual ref components are never
examined, but the refs are still split anyway. Avoiding the split when
we never use the components brings a massive speedup: on my system, the
included benchmark goes from ~1500 us/it to ~180 us/it.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
This commit is contained in:
Ryan Gonzalez
2023-09-13 10:41:00 -05:00
committed by André Roth
parent 8ab8398c50
commit 5636a9990b
2 changed files with 58 additions and 25 deletions
+28 -25
View File
@@ -310,38 +310,41 @@ func (l *PackageRefList) Merge(r *PackageRefList, overrideMatching, ignoreConfli
overridenName = nil overridenName = nil
overriddenArch = nil overriddenArch = nil
} else { } else {
partsL := bytes.Split(rl, []byte(" ")) if !ignoreConflicting || overrideMatching {
archL, nameL, versionL := partsL[0][1:], partsL[1], partsL[2] partsL := bytes.Split(rl, []byte(" "))
archL, nameL, versionL := partsL[0][1:], partsL[1], partsL[2]
partsR := bytes.Split(rr, []byte(" ")) partsR := bytes.Split(rr, []byte(" "))
archR, nameR, versionR := partsR[0][1:], partsR[1], partsR[2] archR, nameR, versionR := partsR[0][1:], partsR[1], partsR[2]
if !ignoreConflicting && bytes.Equal(archL, archR) && bytes.Equal(nameL, nameR) && bytes.Equal(versionL, versionR) { if !ignoreConflicting && bytes.Equal(archL, archR) &&
// conflicting duplicates with same arch, name, version, but different file hash bytes.Equal(nameL, nameR) && bytes.Equal(versionL, versionR) {
result.Refs = append(result.Refs, r.Refs[ir]) // conflicting duplicates with same arch, name, version, but different file hash
il++
ir++
overridenName = nil
overriddenArch = nil
continue
}
if overrideMatching {
if bytes.Equal(archL, overriddenArch) && bytes.Equal(nameL, overridenName) {
// this package has already been overridden on the right
il++
continue
}
if bytes.Equal(archL, archR) && bytes.Equal(nameL, nameR) {
// override with package from the right
result.Refs = append(result.Refs, r.Refs[ir]) result.Refs = append(result.Refs, r.Refs[ir])
il++ il++
ir++ ir++
overriddenArch = archL overridenName = nil
overridenName = nameL overriddenArch = nil
continue continue
} }
if overrideMatching {
if bytes.Equal(archL, overriddenArch) && bytes.Equal(nameL, overridenName) {
// this package has already been overridden on the right
il++
continue
}
if bytes.Equal(archL, archR) && bytes.Equal(nameL, nameR) {
// override with package from the right
result.Refs = append(result.Refs, r.Refs[ir])
il++
ir++
overriddenArch = archL
overridenName = nameL
continue
}
}
} }
// otherwise append smallest of two // otherwise append smallest of two
+30
View File
@@ -0,0 +1,30 @@
package deb
import (
"fmt"
"sort"
"testing"
)
func BenchmarkReflistSimpleMerge(b *testing.B) {
const count = 4096
l := NewPackageRefList()
r := NewPackageRefList()
for i := 0; i < count; i++ {
if i%2 == 0 {
l.Refs = append(l.Refs, []byte(fmt.Sprintf("Pamd64 pkg%d %d", i, i)))
} else {
r.Refs = append(r.Refs, []byte(fmt.Sprintf("Pamd64 pkg%d %d", i, i)))
}
}
sort.Sort(l)
sort.Sort(r)
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Merge(r, false, true)
}
}