optimization for pool

This commit is contained in:
Andy Pan 2018-07-13 00:11:42 +08:00
parent 5aa4fd3b9d
commit c4a50a1867
4 changed files with 23 additions and 14 deletions

View File

@ -65,6 +65,7 @@ func Release() {
// Errors for the Ants API // Errors for the Ants API
var ( var (
ErrPoolSizeInvalid = errors.New("invalid size for pool") ErrInvalidPoolSize = errors.New("invalid size for pool")
ErrInvalidPoolExpiry = errors.New("invalid expiry for pool")
ErrPoolClosed = errors.New("this pool has been closed") ErrPoolClosed = errors.New("this pool has been closed")
) )

View File

@ -41,8 +41,11 @@ const (
ZiB // 1180591620717411303424 (超过了int64的范围) ZiB // 1180591620717411303424 (超过了int64的范围)
YiB // 1208925819614629174706176 YiB // 1208925819614629174706176
) )
const RunTimes = 1000000 const (
const loop = 10 RunTimes = 1000000
Param = 10
AntsSize = 100000
)
func demoFunc() error { func demoFunc() error {
n := 10 n := 10
@ -68,7 +71,7 @@ func BenchmarkGoroutineWithFunc(b *testing.B) {
for j := 0; j < RunTimes; j++ { for j := 0; j < RunTimes; j++ {
wg.Add(1) wg.Add(1)
go func() { go func() {
demoPoolFunc(loop) demoPoolFunc(Param)
wg.Done() wg.Done()
}() }()
} }
@ -78,7 +81,7 @@ func BenchmarkGoroutineWithFunc(b *testing.B) {
func BenchmarkAntsPoolWithFunc(b *testing.B) { func BenchmarkAntsPoolWithFunc(b *testing.B) {
var wg sync.WaitGroup var wg sync.WaitGroup
p, _ := ants.NewPoolWithFunc(50000, func(i interface{}) error { p, _ := ants.NewPoolWithFunc(AntsSize, func(i interface{}) error {
demoPoolFunc(i) demoPoolFunc(i)
wg.Done() wg.Done()
return nil return nil
@ -88,7 +91,7 @@ func BenchmarkAntsPoolWithFunc(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
for j := 0; j < RunTimes; j++ { for j := 0; j < RunTimes; j++ {
wg.Add(1) wg.Add(1)
p.Serve(loop) p.Serve(Param)
} }
wg.Wait() wg.Wait()
b.Logf("running goroutines: %d", p.Running()) b.Logf("running goroutines: %d", p.Running())
@ -98,19 +101,19 @@ func BenchmarkAntsPoolWithFunc(b *testing.B) {
func BenchmarkGoroutine(b *testing.B) { func BenchmarkGoroutine(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
for j := 0; j < RunTimes; j++ { for j := 0; j < RunTimes; j++ {
go demoPoolFunc(loop) go demoPoolFunc(Param)
} }
} }
} }
func BenchmarkAntsPool(b *testing.B) { func BenchmarkAntsPool(b *testing.B) {
p, _ := ants.NewPoolWithFunc(50000, demoPoolFunc) p, _ := ants.NewPoolWithFunc(AntsSize, demoPoolFunc)
defer p.Release() defer p.Release()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
for j := 0; j < RunTimes; j++ { for j := 0; j < RunTimes; j++ {
p.Serve(loop) p.Serve(Param)
} }
// b.Logf("running goroutines: %d", p.Running()) // b.Logf("running goroutines: %d", p.Running())
} }

View File

@ -95,7 +95,10 @@ func NewPool(size int) (*Pool, error) {
// NewTimingPool generates a instance of ants pool with a custom timed task // NewTimingPool generates a instance of ants pool with a custom timed task
func NewTimingPool(size, expiry int) (*Pool, error) { func NewTimingPool(size, expiry int) (*Pool, error) {
if size <= 0 { if size <= 0 {
return nil, ErrPoolSizeInvalid return nil, ErrInvalidPoolSize
}
if expiry <= 0 {
return nil, ErrInvalidPoolExpiry
} }
p := &Pool{ p := &Pool{
capacity: int32(size), capacity: int32(size),

View File

@ -66,7 +66,6 @@ func (p *PoolWithFunc) monitorAndClear() {
heartbeat := time.NewTicker(p.expiryDuration) heartbeat := time.NewTicker(p.expiryDuration)
go func() { go func() {
for range heartbeat.C { for range heartbeat.C {
time.Sleep(p.expiryDuration)
currentTime := time.Now() currentTime := time.Now()
p.lock.Lock() p.lock.Lock()
idleWorkers := p.workers idleWorkers := p.workers
@ -81,7 +80,7 @@ func (p *PoolWithFunc) monitorAndClear() {
p.running-- p.running--
} }
if n > 0 { if n > 0 {
n += 1 n++
p.workers = idleWorkers[n:] p.workers = idleWorkers[n:]
} }
p.lock.Unlock() p.lock.Unlock()
@ -97,7 +96,10 @@ func NewPoolWithFunc(size int, f pf) (*PoolWithFunc, error) {
// NewTimingPoolWithFunc generates a instance of ants pool with a specific function and a custom timed task // NewTimingPoolWithFunc generates a instance of ants pool with a specific function and a custom timed task
func NewTimingPoolWithFunc(size, expiry int, f pf) (*PoolWithFunc, error) { func NewTimingPoolWithFunc(size, expiry int, f pf) (*PoolWithFunc, error) {
if size <= 0 { if size <= 0 {
return nil, ErrPoolSizeInvalid return nil, ErrInvalidPoolSize
}
if expiry <= 0 {
return nil, ErrInvalidPoolExpiry
} }
p := &PoolWithFunc{ p := &PoolWithFunc{
capacity: int32(size), capacity: int32(size),