[英]How to cache the compiled regex in Go
下面是我的 golang 代碼。 每次調用驗證方法時,都會執行我的編譯方法。 我只想編譯一次,而不是每次我們調用驗證時。
1)怎么做? 2) 我的想法是創建一個在開始時為 nil 的實例變量。 它會在驗證中被延遲初始化。
if (a != nil) {
a, err := regexp.Compile(rras.Cfg.WhiteList)
}
但是,如果我將變量聲明為實例變量,
var a *Regexp; // regexp.Compile returns *Regexp
我的編譯器用紅色下划線。 如何解決?
type RRAS struct {
Cfg *RRAPIConfig
}
type RRAPIConfig struct {
WhiteList string
}
func (rras *RRAS) validate(ctx context.Context) error {
a, err := regexp.Compile(rras.Cfg.WhiteList)
}
var whitelistRegexp = regexp.MustCompile(Cfg.WhiteList)
func (rras *RRAS) validate(ctx context.Context) error {
if !whitelistRegexp.Match(...) {...}
}
這將在導入 package 后立即編譯正則表達式,這通常是在程序啟動時,在 main 方法中的任何代碼執行之前。
var whitelistR struct{
rex *regexp.Regexp
once sync.Once
err error
}
func (rras *RRAS) validate(ctx context.Context) error {
whitelistR.once.Do(func() {
whitelistR.ex, whitelistR.err = regexp.Compile(rras.Cfg.WhiteList)
})
if whitelistR.err != nil {
return fmt.Errorf("could not compile regex: %w", err)
}
if !whitelistR.rex.Match(...) {...}
}
這將在第一次調用該方法時 layzily 編譯正則表達式。 sync.Once
非常重要,因為它是一個同步點,可以保證對正則表達式的訪問不是競爭條件。 對該方法的每次調用都必須等到第一次編譯 Regexp。 之后同步非常快,因為它只使用原子負載。
您還可以在 main 方法中調用go once.Do(...)
以並行初始化正則表達式以加速第一次調用,而不會阻塞其他方法。
幾乎總是使用簡單的 static 初始化。 僅當您確定對性能有影響(基准測試)時才使用同步初始化。 同步訪問時,請始終嘗試使用 go 提供的幫助程序(sync.Once、Mutex、RWMutex 等),因為它們經過優化且不易出錯。
Go Memory Model詳細同步和最佳實踐
Go Data Race Detector你應該對每個復雜的多例程進行競賽測試 go 程序
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.