Skip to content

Commit

Permalink
scoring: reduce allocations for addScore (#670)
Browse files Browse the repository at this point in the history
We add a bit more complexity to addScore but avoid allocating a string if debugScore = false.

Test plan:
I ran a couple of benchmarks and confirmed we don't allocate.
  • Loading branch information
stefanhengl authored Oct 23, 2023
1 parent 5bbf05d commit 0a17ccb
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"math"
"regexp/syntax"
"sort"
"strconv"
"strings"
"time"

Expand All @@ -32,11 +33,20 @@ import (

const maxUInt16 = 0xffff

func (m *FileMatch) addScore(what string, s float64, debugScore bool) {
if s != 0 && debugScore {
m.Debug += fmt.Sprintf("%s:%.2f, ", what, s)
// addScore increments the score of the FileMatch by the computed score. If
// debugScore is true, it also adds a debug string to the FileMatch. If raw is
// -1, it is ignored. Otherwise, it is added to the debug string.
func (m *FileMatch) addScore(what string, computed float64, raw float64, debugScore bool) {
if computed != 0 && debugScore {
var b strings.Builder
fmt.Fprintf(&b, "%s", what)
if raw != -1 {
fmt.Fprintf(&b, "(%s)", strconv.FormatFloat(raw, 'f', -1, 64))
}
fmt.Fprintf(&b, ":%.2f, ", computed)
m.Debug += b.String()
}
m.Score += s
m.Score += computed
}

func (m *FileMatch) addKeywordScore(score float64, sumTf float64, L float64, debugScore bool) {
Expand Down Expand Up @@ -408,10 +418,14 @@ func (d *indexData) scoreFile(fileMatch *FileMatch, doc uint32, mt matchTree, kn
atomMatchCount++
})

addScore := func(what string, computed float64) {
fileMatch.addScore(what, computed, -1, opts.DebugScore)
}

// atom-count boosts files with matches from more than 1 atom. The
// maximum boost is scoreFactorAtomMatch.
if atomMatchCount > 0 {
fileMatch.addScore(fmt.Sprintf("atom(%d)", atomMatchCount), (1.0-1.0/float64(atomMatchCount))*scoreFactorAtomMatch, opts.DebugScore)
fileMatch.addScore("atom", (1.0-1.0/float64(atomMatchCount))*scoreFactorAtomMatch, float64(atomMatchCount), opts.DebugScore)
}

maxFileScore := 0.0
Expand All @@ -436,7 +450,7 @@ func (d *indexData) scoreFile(fileMatch *FileMatch, doc uint32, mt matchTree, kn
// Maintain ordering of input files. This
// strictly dominates the in-file ordering of
// the matches.
fileMatch.addScore("fragment", maxFileScore, opts.DebugScore)
addScore("fragment", maxFileScore)

if opts.UseDocumentRanks && len(d.ranks) > int(doc) {
weight := scoreFileRankFactor
Expand All @@ -452,13 +466,13 @@ func (d *indexData) scoreFile(fileMatch *FileMatch, doc uint32, mt matchTree, kn
// The file rank represents a log (base 2) count. The log ranks should be bounded at 32, but we
// cap it just in case to ensure it falls in the range [0, 1].
normalized := math.Min(1.0, ranks[0]/32.0)
fileMatch.addScore("file-rank", weight*normalized, opts.DebugScore)
addScore("file-rank", weight*normalized)
}
}

md := d.repoMetaData[d.repos[doc]]
fileMatch.addScore("doc-order", scoreFileOrderFactor*(1.0-float64(doc)/float64(len(d.boundaries))), opts.DebugScore)
fileMatch.addScore("repo-rank", scoreRepoRankFactor*float64(md.Rank)/maxUInt16, opts.DebugScore)
addScore("doc-order", scoreFileOrderFactor*(1.0-float64(doc)/float64(len(d.boundaries))))
addScore("repo-rank", scoreRepoRankFactor*float64(md.Rank)/maxUInt16)

if opts.DebugScore {
fileMatch.Debug = strings.TrimSuffix(fileMatch.Debug, ", ")
Expand Down

0 comments on commit 0a17ccb

Please sign in to comment.