-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add lazy loading to regular expressions (#16)
## Motivation We should aim at limiting initial load time when importing the library, one of the contributors to the initial load time are compilations of regular expressions. We should avoid loading all of them at once, but rather lazy load the ones which are used by users once. ## Related Changes go-playground/validator#1277 ## Release Notes All regular expressions are now lazy loaded, once when the corresponding rule is used.
- Loading branch information
1 parent
69a9aeb
commit 73dd5a3
Showing
3 changed files
with
54 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package rules | ||
|
||
import ( | ||
"regexp" | ||
"sync" | ||
) | ||
|
||
// nolint: lll | ||
// Define all regular expressions here: | ||
var ( | ||
validUUIDRegexp = lazyRegexCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`) | ||
asciiRegexp = lazyRegexCompile(`^[\x00-\x7F]*$`) | ||
) | ||
|
||
// lazyRegexCompile returns a function that compiles the regular expression | ||
// once, when the function is called for the first time. | ||
// If the function is never called, the regular expression is never compiled, | ||
// thus saving on performance. | ||
// | ||
// All regular expression literals should be compiled using this function. | ||
// | ||
// Credits: https://github.com/go-playground/validator/commit/2e1df48b5ab876bdd461bdccc51d109389e7572f | ||
func lazyRegexCompile(str string) func() *regexp.Regexp { | ||
var ( | ||
regex *regexp.Regexp | ||
once sync.Once | ||
) | ||
return func() *regexp.Regexp { | ||
once.Do(func() { | ||
regex = regexp.MustCompile(str) | ||
}) | ||
return regex | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package rules | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestLazyRegexCompile(t *testing.T) { | ||
lazyRegexp := lazyRegexCompile("^test$") | ||
|
||
re1 := lazyRegexp() | ||
assert.True(t, re1.MatchString("test")) | ||
re2 := lazyRegexp() | ||
assert.True(t, re2.MatchString("test")) | ||
|
||
assert.True(t, re1 == re2, "both regular expression must be the same pointer") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters