Skip to content

Commit e0e5a62

Browse files
internal/codegen: cache pattern matching compilations
Type overrides are checked linearly for every codegen'd type. That linear check currently compiles a regexp pattern for every override that's considered. This commit adds a simple memoizing cache so that each pattern is only ever compiled once. This dramatically improves performance of sqlc for users who have many overrides. ngrok's usage of sqlc generate sees a 10x speedup from this change (4s -> 0.4s).
1 parent d64a68b commit e0e5a62

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

internal/pattern/match.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package pattern
33
import (
44
"fmt"
55
"regexp"
6+
"sync"
67
)
78

89
// Match is a wrapper of *regexp.Regexp.
@@ -11,9 +12,33 @@ type Match struct {
1112
*regexp.Regexp
1213
}
1314

15+
var (
16+
matchCache = make(map[string]*Match)
17+
cacheLock sync.RWMutex
18+
)
19+
1420
// Compile takes our match expression as a string, and compiles it into a *Match object.
1521
// Will return an error on an invalid pattern.
16-
func MatchCompile(pattern string) (match *Match, err error) {
22+
func MatchCompile(pattern string) (*Match, error) {
23+
cacheLock.RLock()
24+
matcher, ok := matchCache[pattern]
25+
cacheLock.RUnlock()
26+
if ok {
27+
return matcher, nil
28+
}
29+
30+
matcher, err := matchCompile(pattern)
31+
if err != nil {
32+
return nil, err
33+
}
34+
cacheLock.Lock()
35+
matchCache[pattern] = matcher
36+
cacheLock.Unlock()
37+
38+
return matcher, nil
39+
}
40+
41+
func matchCompile(pattern string) (match *Match, err error) {
1742
regex := ""
1843
escaped := false
1944
arr := []byte(pattern)

0 commit comments

Comments
 (0)