perf: various small improvements (#7357)

Mostly by having more built-in functions check that they
actually *did* something, or can return an operand instead
of allocating a result.

This saves about 200k allocations in `regal lint bundle`.

Signed-off-by: Anders Eknert <anders@styra.com>
This commit is contained in:
Anders Eknert
2025-02-28 12:59:43 +01:00
committed by GitHub
parent e46696e66e
commit d6b8e6dd26
5 changed files with 49 additions and 1 deletions
+23
View File
@@ -63,6 +63,29 @@ func HasInternedIntNumberTerm(i int) bool {
return i >= -1 && i < len(intNumberTerms)
}
func InternedStringTerm(s string) *Term {
if term, ok := internedStringTerms[s]; ok {
return term
}
return StringTerm(s)
}
var internedStringTerms = map[string]*Term{
"": InternedEmptyString,
"0": StringTerm("0"),
"1": StringTerm("1"),
"2": StringTerm("2"),
"3": StringTerm("3"),
"4": StringTerm("4"),
"5": StringTerm("5"),
"6": StringTerm("6"),
"7": StringTerm("7"),
"8": StringTerm("8"),
"9": StringTerm("9"),
"10": StringTerm("10"),
}
var stringToIntNumberTermMap = map[string]*Term{
"-1": minusOneTerm,
"0": intNumberTerms[0],
+4
View File
@@ -1641,6 +1641,10 @@ func (p *Parser) parseNumber() *Term {
func (p *Parser) parseString() *Term {
if p.s.lit[0] == '"' {
if p.s.lit == "\"\"" {
return NewTerm(InternedEmptyString.Value).SetLocation(p.s.Loc())
}
var s string
err := json.Unmarshal([]byte(p.s.lit), &s)
if err != nil {
+10
View File
@@ -21,6 +21,16 @@ func builtinObjectUnion(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T
return err
}
if objA.Len() == 0 {
return iter(operands[1])
}
if objB.Len() == 0 {
return iter(operands[0])
}
if objA.Compare(objB) == 0 {
return iter(operands[0])
}
r := mergeWithOverwrite(objA, objB)
return iter(ast.NewTerm(r))
+3
View File
@@ -260,6 +260,9 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a
}
res := re.ReplaceAllString(string(base), string(value))
if res == string(base) {
return iter(operands[0])
}
return iter(ast.StringTerm(res))
}
+9 -1
View File
@@ -324,6 +324,10 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
return iter(ast.StringTerm(sbase[startIndex:]))
}
if startIndex == 0 && length >= len(sbase) {
return iter(operands[0])
}
upto := startIndex + length
if len(sbase) < upto {
upto = len(sbase)
@@ -331,6 +335,10 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
return iter(ast.StringTerm(sbase[startIndex:upto]))
}
if startIndex == 0 && length >= utf8.RuneCountInString(sbase) {
return iter(operands[0])
}
runes := []rune(base)
if startIndex >= len(runes) {
@@ -641,7 +649,7 @@ func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
if s == "%d" && astArr.Len() == 1 {
if n, ok := astArr.Elem(0).Value.(ast.Number); ok {
if i, ok := n.Int(); ok {
return iter(ast.StringTerm(strconv.Itoa(i)))
return iter(ast.InternedStringTerm(strconv.Itoa(i)))
}
}
}