diff --git a/glob_test.go b/glob_test.go index 08de6f7..35a7267 100644 --- a/glob_test.go +++ b/glob_test.go @@ -1,8 +1,6 @@ package glob import ( - "fmt" - "github.com/gobwas/glob/match" "regexp" "testing" ) @@ -152,13 +150,6 @@ func TestGlob(t *testing.T) { } } -func TestAllGlobMatch(t *testing.T) { - - m, _ := Compile(pattern_all) - fmt.Println("HI", m.(match.Matcher).String()) - m.Match(fixture_all_match) -} - func BenchmarkParseGlob(b *testing.B) { for i := 0; i < b.N; i++ { Compile(pattern_all) @@ -186,6 +177,7 @@ func BenchmarkAllGlobMatchParallel(b *testing.B) { } }) } + func BenchmarkAllRegexpMatch(b *testing.B) { m := regexp.MustCompile(regexp_all) f := []byte(fixture_all_match) diff --git a/match/btree.go b/match/btree.go index a9a7a15..2358eb3 100644 --- a/match/btree.go +++ b/match/btree.go @@ -77,7 +77,6 @@ func (self BTree) Match(s string) bool { limit = inputLen } - fmt.Println("ACQUIRE") in := acquireSegments(inputLen) for offset < limit { diff --git a/match/match.go b/match/match.go index 9df55fd..a8351eb 100644 --- a/match/match.go +++ b/match/match.go @@ -54,7 +54,6 @@ func init() { func(i int) { segmentsPools[i-1] = sync.Pool{ New: func() interface{} { - fmt.Println("NEW", i) return make([]int, 0, i) }, } @@ -75,12 +74,10 @@ func getIdx(c int) int { } func acquireSegments(c int) []int { - fmt.Println("GET", getIdx(c)) return segmentsPools[getIdx(c)].Get().([]int)[:0] } func releaseSegments(s []int) { - fmt.Println("PUT", getIdx(cap(s))) segmentsPools[getIdx(cap(s))].Put(s) } diff --git a/match/segements_test.go b/match/segements_test.go new file mode 100644 index 0000000..2fcbe17 --- /dev/null +++ b/match/segements_test.go @@ -0,0 +1,37 @@ +package match + +import ( + "testing" +) + +func BenchmarkPerfPoolSequenced(b *testing.B) { + pool := NewPoolSequenced(32, 32) + + for i := 0; i < b.N; i++ { + s := pool.Get() + pool.Put(s) + } +} + +func BenchmarkPerfPoolSynced(b *testing.B) { + pool := NewPoolSynced(32) + + for i := 0; i < b.N; i++ { + s := pool.Get() + pool.Put(s) + } +} +func BenchmarkPerfPoolPoolNative(b *testing.B) { + pool := NewPoolNative(32) + + for i := 0; i < b.N; i++ { + s := pool.Get() + pool.Put(s) + } +} + +func BenchmarkPerfMake(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = make([]int, 0, 32) + } +} diff --git a/match/segments.go b/match/segments.go new file mode 100644 index 0000000..bd099e3 --- /dev/null +++ b/match/segments.go @@ -0,0 +1,97 @@ +package match + +import "sync" + +// Pool holds Clients. +type PoolSequenced struct { + size int + pool chan []int +} + +// NewPool creates a new pool of Clients. +func NewPoolSequenced(max, size int) *PoolSequenced { + return &PoolSequenced{ + size: size, + pool: make(chan []int, max), + } +} + +// Borrow a Client from the pool. +func (p *PoolSequenced) Get() []int { + var s []int + select { + case s = <-p.pool: + default: + s = make([]int, 0, p.size) + } + + return s[:0] +} + +// Return returns a Client to the pool. +func (p *PoolSequenced) Put(s []int) { + select { + case p.pool <- s: + default: + // let it go, let it go... + } +} + +type PoolSynced struct { + size int + mu sync.Mutex + list [][]int +} + +func NewPoolSynced(size int) *PoolSynced { + return &PoolSynced{ + size: size, + } +} + +func (p *PoolSynced) Get() []int { + var s []int + + p.mu.Lock() + ll := len(p.list) + if ll > 0 { + s, p.list = p.list[ll-1], p.list[:ll-1] + } + p.mu.Unlock() + + if s == nil { + return make([]int, 0, p.size) + } + + return s[:0] +} + +func (p *PoolSynced) Put(s []int) { + p.mu.Lock() + defer p.mu.Unlock() + p.list = append(p.list, s) +} + +type PoolNative struct { + size int + pool sync.Pool +} + +func NewPoolNative(size int) *PoolNative { + return &PoolNative{ + size: size, + } +} + +func (p *PoolNative) Get() []int { + s := p.pool.Get() + if s == nil { + return make([]int, 0, p.size) + } + + return s.([]int) +} + +func (p *PoolNative) Put(s []int) { + p.pool.Put(s) +}