Skip to content

Commit d6b8e6d

Browse files
authored
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 <[email protected]>
1 parent e46696e commit d6b8e6d

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

v1/ast/interning.go

+23
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,29 @@ func HasInternedIntNumberTerm(i int) bool {
6363
return i >= -1 && i < len(intNumberTerms)
6464
}
6565

66+
func InternedStringTerm(s string) *Term {
67+
if term, ok := internedStringTerms[s]; ok {
68+
return term
69+
}
70+
71+
return StringTerm(s)
72+
}
73+
74+
var internedStringTerms = map[string]*Term{
75+
"": InternedEmptyString,
76+
"0": StringTerm("0"),
77+
"1": StringTerm("1"),
78+
"2": StringTerm("2"),
79+
"3": StringTerm("3"),
80+
"4": StringTerm("4"),
81+
"5": StringTerm("5"),
82+
"6": StringTerm("6"),
83+
"7": StringTerm("7"),
84+
"8": StringTerm("8"),
85+
"9": StringTerm("9"),
86+
"10": StringTerm("10"),
87+
}
88+
6689
var stringToIntNumberTermMap = map[string]*Term{
6790
"-1": minusOneTerm,
6891
"0": intNumberTerms[0],

v1/ast/parser.go

+4
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,10 @@ func (p *Parser) parseNumber() *Term {
16411641

16421642
func (p *Parser) parseString() *Term {
16431643
if p.s.lit[0] == '"' {
1644+
if p.s.lit == "\"\"" {
1645+
return NewTerm(InternedEmptyString.Value).SetLocation(p.s.Loc())
1646+
}
1647+
16441648
var s string
16451649
err := json.Unmarshal([]byte(p.s.lit), &s)
16461650
if err != nil {

v1/topdown/object.go

+10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ func builtinObjectUnion(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T
2121
return err
2222
}
2323

24+
if objA.Len() == 0 {
25+
return iter(operands[1])
26+
}
27+
if objB.Len() == 0 {
28+
return iter(operands[0])
29+
}
30+
if objA.Compare(objB) == 0 {
31+
return iter(operands[0])
32+
}
33+
2434
r := mergeWithOverwrite(objA, objB)
2535

2636
return iter(ast.NewTerm(r))

v1/topdown/regex.go

+3
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a
260260
}
261261

262262
res := re.ReplaceAllString(string(base), string(value))
263+
if res == string(base) {
264+
return iter(operands[0])
265+
}
263266

264267
return iter(ast.StringTerm(res))
265268
}

v1/topdown/strings.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,21 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
324324
return iter(ast.StringTerm(sbase[startIndex:]))
325325
}
326326

327+
if startIndex == 0 && length >= len(sbase) {
328+
return iter(operands[0])
329+
}
330+
327331
upto := startIndex + length
328332
if len(sbase) < upto {
329333
upto = len(sbase)
330334
}
331335
return iter(ast.StringTerm(sbase[startIndex:upto]))
332336
}
333337

338+
if startIndex == 0 && length >= utf8.RuneCountInString(sbase) {
339+
return iter(operands[0])
340+
}
341+
334342
runes := []rune(base)
335343

336344
if startIndex >= len(runes) {
@@ -641,7 +649,7 @@ func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
641649
if s == "%d" && astArr.Len() == 1 {
642650
if n, ok := astArr.Elem(0).Value.(ast.Number); ok {
643651
if i, ok := n.Int(); ok {
644-
return iter(ast.StringTerm(strconv.Itoa(i)))
652+
return iter(ast.InternedStringTerm(strconv.Itoa(i)))
645653
}
646654
}
647655
}

0 commit comments

Comments
 (0)