mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
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:
@@ -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],
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user