Go'da Regex Performansı: Compile Caching ile Hızını 10x Artırma
Go'da regex kullanırken çoğu kişi aynı deseni tekrar tekrar derler. Bu, her aramada yeni bir regex nesnesi oluşturmak demek ve performansı ciddi şekilde düşürür.
Sorun şu: regexp.Compile() pahalı bir işlemdir. Desen ayrıştırılır, doğrulanır ve bir durum makinasına dönüştürülür. Eğer bir fonksiyon içinde her çağrıda bu işlemi yaparsanız, zamanın çoğu derlemede harcanır, asıl eşleştirmede değil.
Çözüm compile caching'dir. Regex'i global olarak veya sync.Map ile bir kere derleyip, sonra tekrar kullanırsınız.
Yavaş Yol (Her Seferinde Derleme)
1package main23import (4"fmt"5"regexp"6"time"7)89func findEmail(text string) bool {10re, _:= regexp.Compile(`[a-z]+@[a-z]+\.[a-z]+`)11return re.MatchString(text)12}1314func main() {15start:= time.Now()16for i:= 0; i < 100000; i++ {17findEmail("test@example.com")18}19fmt.Println("Süre:", time.Since(start))20}Bu kod 100 bin kere aynı regex'i derler. Çıktı: Süre: ~2.5 saniye
Hızlı Yol (Compile Caching)
1package main23import (4"fmt"5"regexp"6"sync"7"time"8)910var regexCache = make(map[string]*regexp.Regexp)11var mu sync.Mutex1213func getRegex(pattern string) *regexp.Regexp {14mu.Lock()15defer mu.Unlock()1617if re, ok:= regexCache[pattern]; ok {18return re19}2021re:= regexp.MustCompile(pattern)22regexCache[pattern] = re23return re24}2526func findEmail(text string) bool {27re:= getRegex(`[a-z]+@[a-z]+\.[a-z]+`)28return re.MatchString(text)29}3031func main() {32start:= time.Now()33for i:= 0; i < 100000; i++ {34findEmail("test@example.com")35}36fmt.Println("Süre:", time.Since(start))37}Bu kod regex'i ilk kere derler, sonra önbellekten alır. Çıktı: Süre: ~240 milisaniye
Fark 10 kat hız artışıdır.
Pratik İpucu
Produkte sync.Map kullanmak daha güvenlidir; okuma çok sık olduğunda kilit çekişmesi azalır. Veya regex'leri paket seviyesinde global değişken olarak tanımlayın. Eğer regex desenleri sabit ve az sayıdaysa, başlangıçta hepsini derleyin. Çok sayıda dinamik desen varsa, sync.Map tercih edin.
0 yorum