diff --git a/g/container/gtype/gtype_test.go b/g/container/gtype/gtype_test.go index 30e88bc36..5cf65366c 100644 --- a/g/container/gtype/gtype_test.go +++ b/g/container/gtype/gtype_test.go @@ -6,25 +6,24 @@ // go test *.go -bench=".*" -package gtype_test +package gtype import ( "testing" - "gitee.com/johng/gf/g/container/gtype" "strconv" "gitee.com/johng/gf/g/encoding/gbinary" ) -var it = gtype.NewInt() -var it32 = gtype.NewInt32() -var it64 = gtype.NewInt64() -var uit = gtype.NewUint() -var uit32 = gtype.NewUint32() -var uit64 = gtype.NewUint64() -var bl = gtype.NewBool() -var bytes = gtype.NewBytes() -var str = gtype.NewString() -var inf = gtype.NewInterface() +var it = NewInt() +var it32 = NewInt32() +var it64 = NewInt64() +var uit = NewUint() +var uit32 = NewUint32() +var uit64 = NewUint64() +var bl = NewBool() +var bytes = NewBytes() +var str = NewString() +var inf = NewInterface() func BenchmarkInt_Set(b *testing.B) { for i := 0; i < b.N; i++ { diff --git a/g/os/gcache/gcache.go b/g/os/gcache/gcache.go index 2fbde1ac6..487a8d454 100644 --- a/g/os/gcache/gcache.go +++ b/g/os/gcache/gcache.go @@ -26,7 +26,7 @@ type Cache struct { dmu sync.RWMutex // data锁 emu sync.RWMutex // ekmap锁 smu sync.RWMutex // eksets锁 - lru *_Lru // LRU缓存限制 + lru *_Lru // LRU缓存限制(只有限定池大小时才启用) cap *gtype.Int // 控制缓存池大小,超过大小则按照LRU算法进行缓存过期处理(默认为0表示不进行限制) data map[string]_CacheItem // 缓存数据(所有的缓存数据存放哈希表) ekmap map[string]int64 // 键名对应的分组过期时间(用于相同键名过期时间快速更新) @@ -290,14 +290,13 @@ func (c *Cache) autoSyncLoop() { c.ekmap[item.k] = newe c.emu.Unlock() // LRU操作记录(只有新增和修改操作才会记录到LRU管理对象中,删除不会) - if newe >= olde { + if newe >= olde && c.cap.Val() > 0 { c.lru.Push(item.k) } } else { return } } - } // LRU缓存淘汰处理+自动清理过期键值对 diff --git a/g/os/gcache/gcache_test.go b/g/os/gcache/gcache_test.go index 5adf05f93..ed6908b2e 100644 --- a/g/os/gcache/gcache_test.go +++ b/g/os/gcache/gcache_test.go @@ -6,29 +6,28 @@ // go test *.go -bench=".*" -package gcache_test +package gcache import ( "testing" "strconv" - "gitee.com/johng/gf/g/os/gcache" ) func BenchmarkSet(b *testing.B) { for i := 0; i < b.N; i++ { - gcache.Set(strconv.Itoa(i), strconv.Itoa(i), 0) + Set(strconv.Itoa(i), strconv.Itoa(i), 0) } } func BenchmarkGet(b *testing.B) { for i := 0; i < b.N; i++ { - gcache.Get(strconv.Itoa(i)) + Get(strconv.Itoa(i)) } } func BenchmarkRemove(b *testing.B) { for i := 0; i < b.N; i++ { - gcache.Remove(strconv.Itoa(i)) + Remove(strconv.Itoa(i)) } } \ No newline at end of file diff --git a/g/util/gregx/regx.go b/g/util/gregx/regx.go index 1a11f4023..e96cea8c6 100644 --- a/g/util/gregx/regx.go +++ b/g/util/gregx/regx.go @@ -1,4 +1,4 @@ -// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// Copyright 2017-2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -9,21 +9,37 @@ package gregx import ( "regexp" + "gitee.com/johng/gf/g/os/gcache" ) +// 缓存对象,主要用于缓存底层regx对象 +var regxCache = gcache.New() + +// 根据pattern生成对应的regexp正则对象 +func getRegexp(pattern string) (*regexp.Regexp, error) { + if v := regxCache.Get(pattern); v != nil { + return v.(*regexp.Regexp), nil + } + if r, err := regexp.Compile(pattern); err == nil { + regxCache.Set(pattern, r, 0) + return r, nil + } else { + return nil, err + } +} + // 校验所给定的正则表达式是否符合规范 func Validate(pattern string) error { - _, err := regexp.Compile(pattern) + _, err := getRegexp(pattern) return err } // 正则表达式是否匹配 func IsMatch(pattern string, src []byte) bool { - match, err := regexp.Match(pattern, src) - if err != nil { - return false + if r, err := getRegexp(pattern); err == nil { + return r.Match(src) } - return match + return false } func IsMatchString(pattern string, src string) bool { @@ -32,30 +48,28 @@ func IsMatchString(pattern string, src string) bool { // 正则匹配,并返回匹配的列表 func MatchString(pattern string, src string) ([]string, error) { - reg, err := regexp.Compile(pattern) - if err != nil { + if r, err := getRegexp(pattern); err == nil { + return r.FindStringSubmatch(src), nil + } else { return nil, err } - s := reg.FindStringSubmatch(src) - return s, nil } func MatchAllString(pattern string, src string) ([][]string, error) { - reg, err := regexp.Compile(pattern) - if err != nil { + if r, err := getRegexp(pattern); err == nil { + return r.FindAllStringSubmatch(src, -1), nil + } else { return nil, err } - s := reg.FindAllStringSubmatch(src, -1) - return s, nil } // 正则替换(全部替换) func Replace(pattern string, replace, src []byte) ([]byte, error) { - reg, err := regexp.Compile(pattern) - if err != nil { - return src, err + if r, err := getRegexp(pattern); err == nil { + return r.ReplaceAll(src, replace), nil + } else { + return nil, err } - return reg.ReplaceAll(src, replace), nil } // 正则替换(全部替换),字符串 diff --git a/g/util/gregx/regx_test.go b/g/util/gregx/regx_test.go new file mode 100644 index 000000000..d323d2fbb --- /dev/null +++ b/g/util/gregx/regx_test.go @@ -0,0 +1,59 @@ +// Copyright 2017-2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// go test *.go -bench=".*" + +package gregx + +import ( + "testing" +) + +var pattern = `(.+):(\d+)` +var src = "johng.cn:80" +var replace = "johng.cn" + +func BenchmarkValidate(b *testing.B) { + for i := 0; i < b.N; i++ { + Validate(pattern) + } +} + +func BenchmarkIsMatch(b *testing.B) { + for i := 0; i < b.N; i++ { + IsMatch(pattern, []byte(src)) + } +} + +func BenchmarkIsMatchString(b *testing.B) { + for i := 0; i < b.N; i++ { + IsMatchString(pattern, src) + } +} + +func BenchmarkMatchString(b *testing.B) { + for i := 0; i < b.N; i++ { + MatchString(pattern, src) + } +} + +func BenchmarkMatchAllString(b *testing.B) { + for i := 0; i < b.N; i++ { + MatchAllString(pattern, src) + } +} + +func BenchmarkReplace(b *testing.B) { + for i := 0; i < b.N; i++ { + Replace(pattern, []byte(replace), []byte(src)) + } +} + +func BenchmarkReplaceString(b *testing.B) { + for i := 0; i < b.N; i++ { + ReplaceString(pattern, replace, src) + } +}