mirror of https://github.com/q191201771/naza
1. 删除 package bufferpool 2. package slicebytepool 添加单元测试
parent
36ddcfdb64
commit
b9f6905392
@ -1,141 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/q191201771/naza/pkg/bufferpool"
|
||||
"github.com/q191201771/naza/pkg/nazalog"
|
||||
)
|
||||
|
||||
var bp bufferpool.BufferPool
|
||||
|
||||
//var count int32
|
||||
var doneCount uint32
|
||||
|
||||
var gorutineNum = 1000
|
||||
var loopNum = 1000
|
||||
var sleepMSec = time.Duration(10) * time.Millisecond
|
||||
|
||||
func size() int {
|
||||
return random(1, 256*1024)
|
||||
|
||||
//return 128 * 1024
|
||||
|
||||
//ss := []int{1000, 2000, 5000}
|
||||
//////ss := []int{128, 1024, 4096, 16384}
|
||||
//atomic.AddInt32(&count, 1)
|
||||
//return ss[count % 3]
|
||||
|
||||
//count++
|
||||
//if count > 128 * 1024 {
|
||||
// count = 1
|
||||
//}
|
||||
//return count
|
||||
}
|
||||
|
||||
func random(l, r int) int {
|
||||
return l + (rand.Int() % (r - l))
|
||||
}
|
||||
|
||||
func originFunc() {
|
||||
var buf bytes.Buffer
|
||||
size := size()
|
||||
buf.Grow(size)
|
||||
atomic.AddUint32(&doneCount, 1)
|
||||
time.Sleep(sleepMSec)
|
||||
}
|
||||
|
||||
func bufferPoolFunc() {
|
||||
size := size()
|
||||
buf := bp.Get(size)
|
||||
buf.Grow(size)
|
||||
time.Sleep(sleepMSec)
|
||||
bp.Put(buf)
|
||||
atomic.AddUint32(&doneCount, 1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
strategy := parseFlag()
|
||||
nazalog.Debugf("strategy: %d", strategy)
|
||||
|
||||
//cpufd, err := os.Create("/tmp/cpu.prof")
|
||||
//nazalog.FatalIfErrorNotNil(err)
|
||||
//pprof.StartCPUProfile(cpufd)
|
||||
//defer pprof.StopCPUProfile()
|
||||
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
if strategy != 5 {
|
||||
bp = bufferpool.NewBufferPool(bufferpool.Strategy(strategy))
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
if strategy != 5 {
|
||||
nazalog.Debugf("time. done=%d, pool=%+v", atomic.LoadUint32(&doneCount), bp.RetrieveStatus())
|
||||
time.Sleep(1 * time.Second)
|
||||
} else {
|
||||
nazalog.Debugf("time. done=%d", atomic.LoadUint32(&doneCount))
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(gorutineNum * loopNum)
|
||||
nazalog.Debug("> loop.")
|
||||
for i := 0; i < gorutineNum; i++ {
|
||||
go func() {
|
||||
if strategy != 5 {
|
||||
for j := 0; j < loopNum; j++ {
|
||||
bufferPoolFunc()
|
||||
wg.Done()
|
||||
}
|
||||
} else {
|
||||
for j := 0; j < loopNum; j++ {
|
||||
originFunc()
|
||||
wg.Done()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
memfd, err := os.Create(fmt.Sprintf("/tmp/mem%d.prof", strategy))
|
||||
nazalog.FatalIfErrorNotNil(err)
|
||||
pprof.WriteHeapProfile(memfd)
|
||||
memfd.Close()
|
||||
nazalog.Debug("> GC.")
|
||||
runtime.GC()
|
||||
nazalog.Debug("< GC.")
|
||||
if strategy != 5 {
|
||||
nazalog.Debugf("%+v", bp.RetrieveStatus())
|
||||
}
|
||||
nazalog.Debug("< loop.")
|
||||
}
|
||||
|
||||
func parseFlag() int {
|
||||
strategy := flag.Int("t", 0, "type: 1. single std pool 2. single slice pool 3. multi std pool 4. multi slice pool 5. origin")
|
||||
flag.Parse()
|
||||
if *strategy < 1 || *strategy > 5 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
return *strategy
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package bufferpool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var bp BufferPool
|
||||
var count int32
|
||||
|
||||
func size() int {
|
||||
return random(0, 128*1024)
|
||||
|
||||
//return 128 * 1024
|
||||
|
||||
//ss := []int{1000, 2000, 5000}
|
||||
//////ss := []int{128, 1024, 4096, 16384}
|
||||
//atomic.AddInt32(&count, 1)
|
||||
//return ss[count % 3]
|
||||
|
||||
//count++
|
||||
//if count > 128 * 1024 {
|
||||
// count = 1
|
||||
//}
|
||||
//return count
|
||||
}
|
||||
|
||||
func random(l, r int) int {
|
||||
return l + (rand.Int() % (r - l))
|
||||
}
|
||||
|
||||
func originFunc() {
|
||||
var buf bytes.Buffer
|
||||
size := size()
|
||||
buf.Grow(size)
|
||||
}
|
||||
|
||||
func bufferPoolFunc() {
|
||||
size := size()
|
||||
buf := bp.Get(size)
|
||||
buf.Grow(size)
|
||||
bp.Put(buf)
|
||||
}
|
||||
|
||||
func BenchmarkOrigin(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
originFunc()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBufferPool(b *testing.B) {
|
||||
bp = NewBufferPool(StrategyMultiStdPoolBucket)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
bufferPoolFunc()
|
||||
}
|
||||
//nazalog.Debugf("%+v", bp.RetrieveStatus())
|
||||
}
|
||||
|
||||
//func BenchmarkOriginParallel(b *testing.B) {
|
||||
// for i := 0; i < b.N; i++ {
|
||||
// b.RunParallel(func(pb *testing.PB) {
|
||||
// for pb.Next() {
|
||||
// originFunc()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func BenchmarkBufferPoolParallel(b *testing.B) {
|
||||
// bp = NewBufferPool()
|
||||
// b.ResetTimer()
|
||||
// for i := 0; i < b.N; i++ {
|
||||
// b.RunParallel(func(pb *testing.PB) {
|
||||
// for pb.Next() {
|
||||
// bufferPoolFunc()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// //nazalog.Debugf("%+v", bp.RetrieveStatus())
|
||||
//}
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package bufferpool
|
||||
|
||||
import "bytes"
|
||||
|
||||
var defaultPool BufferPool
|
||||
|
||||
func Get(size int) *bytes.Buffer {
|
||||
return defaultPool.Get(size)
|
||||
}
|
||||
|
||||
func Put(buf *bytes.Buffer) {
|
||||
defaultPool.Put(buf)
|
||||
}
|
||||
|
||||
func RetrieveStatus() Status {
|
||||
return defaultPool.RetrieveStatus()
|
||||
}
|
||||
|
||||
func Init(strategy Strategy) {
|
||||
defaultPool = NewBufferPool(strategy)
|
||||
}
|
||||
|
||||
func init() {
|
||||
Init(StrategyMultiStdPoolBucket)
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package bufferpool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/q191201771/naza/pkg/nazaatomic"
|
||||
)
|
||||
|
||||
type SharedBuffer struct {
|
||||
*bytes.Buffer
|
||||
pool BufferPool
|
||||
count *nazaatomic.Uint32
|
||||
}
|
||||
|
||||
func NewSharedBufferDefault(size int) *SharedBuffer {
|
||||
return NewSharedBuffer(defaultPool, size)
|
||||
}
|
||||
|
||||
func NewSharedBuffer(pool BufferPool, size int) *SharedBuffer {
|
||||
return &SharedBuffer{
|
||||
Buffer: pool.Get(size),
|
||||
count: new(nazaatomic.Uint32),
|
||||
}
|
||||
}
|
||||
|
||||
func (sb *SharedBuffer) Ref() *SharedBuffer {
|
||||
sb.count.Increment()
|
||||
return sb
|
||||
}
|
||||
|
||||
func (sb *SharedBuffer) ReleaseIfNeeded() {
|
||||
if sb.count.Decrement() == 0 {
|
||||
sb.pool.Put(sb.Buffer)
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package bufferpool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type SliceBucket struct {
|
||||
m sync.Mutex
|
||||
core []*bytes.Buffer
|
||||
}
|
||||
|
||||
func NewSliceBucket() *SliceBucket {
|
||||
return new(SliceBucket)
|
||||
}
|
||||
|
||||
func (b *SliceBucket) Get() *bytes.Buffer {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
if len(b.core) == 0 {
|
||||
return nil
|
||||
}
|
||||
buf := b.core[len(b.core)-1]
|
||||
b.core = b.core[:len(b.core)-1]
|
||||
buf.Reset()
|
||||
return buf
|
||||
}
|
||||
|
||||
func (b *SliceBucket) Put(buf *bytes.Buffer) {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
b.core = append(b.core, buf)
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2019, Chef. All rights reserved.
|
||||
// https://github.com/q191201771/naza
|
||||
//
|
||||
// Use of this source code is governed by a MIT-style license
|
||||
// that can be found in the License file.
|
||||
//
|
||||
// Author: Chef (191201771@qq.com)
|
||||
|
||||
package bufferpool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type StdPoolBucket struct {
|
||||
core *sync.Pool
|
||||
}
|
||||
|
||||
func NewStdPoolBucket() *StdPoolBucket {
|
||||
return &StdPoolBucket{
|
||||
core: new(sync.Pool),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *StdPoolBucket) Get() *bytes.Buffer {
|
||||
v := b.core.Get()
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
vv := v.(*bytes.Buffer)
|
||||
vv.Reset()
|
||||
return vv
|
||||
}
|
||||
|
||||
func (b *StdPoolBucket) Put(buf *bytes.Buffer) {
|
||||
b.core.Put(buf)
|
||||
}
|
Loading…
Reference in New Issue