diff --git a/internal/stats/user_agent_parser.go b/internal/stats/user_agent_parser.go index 3ada2a2..b0d74d1 100644 --- a/internal/stats/user_agent_parser.go +++ b/internal/stats/user_agent_parser.go @@ -4,6 +4,7 @@ package stats import ( "github.com/TeaOSLab/EdgeNode/internal/utils" + "github.com/TeaOSLab/EdgeNode/internal/utils/fnv" "github.com/mssola/user_agent" "sync" ) @@ -14,8 +15,8 @@ var SharedUserAgentParser = NewUserAgentParser() type UserAgentParser struct { parser *user_agent.UserAgent - cacheMap1 map[string]UserAgentParserResult - cacheMap2 map[string]UserAgentParserResult + cacheMap1 map[uint64]UserAgentParserResult + cacheMap2 map[uint64]UserAgentParserResult maxCacheItems int cacheCursor int @@ -25,8 +26,8 @@ type UserAgentParser struct { func NewUserAgentParser() *UserAgentParser { var parser = &UserAgentParser{ parser: &user_agent.UserAgent{}, - cacheMap1: map[string]UserAgentParserResult{}, - cacheMap2: map[string]UserAgentParserResult{}, + cacheMap1: map[uint64]UserAgentParserResult{}, + cacheMap2: map[uint64]UserAgentParserResult{}, cacheCursor: 0, } @@ -53,14 +54,16 @@ func (this *UserAgentParser) Parse(userAgent string) (result UserAgentParserResu return } + var userAgentKey = fnv.HashString(userAgent) + this.locker.RLock() - cacheResult, ok := this.cacheMap1[userAgent] + cacheResult, ok := this.cacheMap1[userAgentKey] if ok { this.locker.RUnlock() return cacheResult } - cacheResult, ok = this.cacheMap2[userAgent] + cacheResult, ok = this.cacheMap2[userAgentKey] if ok { this.locker.RUnlock() return cacheResult @@ -85,16 +88,16 @@ func (this *UserAgentParser) Parse(userAgent string) (result UserAgentParserResu } if this.cacheCursor == 0 { - this.cacheMap1[userAgent] = result + this.cacheMap1[userAgentKey] = result if len(this.cacheMap1) >= this.maxCacheItems { this.cacheCursor = 1 - this.cacheMap2 = map[string]UserAgentParserResult{} + this.cacheMap2 = map[uint64]UserAgentParserResult{} } } else { - this.cacheMap2[userAgent] = result + this.cacheMap2[userAgentKey] = result if len(this.cacheMap2) >= this.maxCacheItems { this.cacheCursor = 0 - this.cacheMap1 = map[string]UserAgentParserResult{} + this.cacheMap1 = map[uint64]UserAgentParserResult{} } } diff --git a/internal/stats/user_agent_parser_test.go b/internal/stats/user_agent_parser_test.go index f28e7bb..108a407 100644 --- a/internal/stats/user_agent_parser_test.go +++ b/internal/stats/user_agent_parser_test.go @@ -47,7 +47,15 @@ func TestUserAgentParser_Memory(t *testing.T) { func BenchmarkUserAgentParser_Parse(b *testing.B) { var parser = NewUserAgentParser() for i := 0; i < b.N; i++ { - parser.Parse("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Test/" + types.String(rands.Int(0, 40000))) + parser.Parse("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Test/" + types.String(rands.Int(0, 1_000_000))) + } + b.Log(len(parser.cacheMap1), len(parser.cacheMap2)) +} + +func BenchmarkUserAgentParser_Parse2(b *testing.B) { + var parser = NewUserAgentParser() + for i := 0; i < b.N; i++ { + parser.Parse("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Test/" + types.String(rands.Int(0, 100_000))) } b.Log(len(parser.cacheMap1), len(parser.cacheMap2)) }