diff --git a/ants.go b/ants.go index 167c744..a172a6f 100644 --- a/ants.go +++ b/ants.go @@ -25,6 +25,7 @@ package ants import ( "errors" "math" + "runtime" ) const ( @@ -35,6 +36,30 @@ const ( DefaultCleanIntervalTime = 5 ) +var ( + // Error types for the Ants API. + ErrInvalidPoolSize = errors.New("invalid size for pool") + ErrInvalidPoolExpiry = errors.New("invalid expiry for pool") + ErrPoolClosed = errors.New("this pool has been closed") + + // workerChanCap determines whether the channel of a worker should be a buffered channel + // to get the best performance, inspired by fasthttp. + // https://github.com/valyala/fasthttp/blob/master/workerpool.go#L139 + workerChanCap = func() int { + // Use blocking workerChan if GOMAXPROCS=1. + // This immediately switches Serve to WorkerFunc, which results + // in higher performance (under go1.5 at least). + if runtime.GOMAXPROCS(0) == 1 { + return 0 + } + + // Use non-blocking workerChan if GOMAXPROCS>1, + // since otherwise the Serve caller (Acceptor) may lag accepting + // new connections if WorkerFunc is CPU-bound. + return 1 + }() +) + // Init a instance pool when importing ants. var defaultAntsPool, _ = NewPool(DefaultAntsPoolSize) @@ -62,10 +87,3 @@ func Free() int { func Release() { defaultAntsPool.Release() } - -// Error types for the Ants API. -var ( - ErrInvalidPoolSize = errors.New("invalid size for pool") - ErrInvalidPoolExpiry = errors.New("invalid expiry for pool") - ErrPoolClosed = errors.New("this pool has been closed") -) diff --git a/pool.go b/pool.go index b4e8f34..e8fd74e 100644 --- a/pool.go +++ b/pool.go @@ -28,8 +28,6 @@ import ( "time" ) -type sig struct{} - type f func() // Pool accept the tasks from client,it limits the total @@ -222,7 +220,7 @@ func (p *Pool) getWorker() *Worker { } else if w == nil { w = &Worker{ pool: p, - task: make(chan f, 1), + task: make(chan f, workerChanCap), } w.run() p.incRunning() diff --git a/pool_func.go b/pool_func.go index ddf3034..f3609e9 100644 --- a/pool_func.go +++ b/pool_func.go @@ -224,7 +224,7 @@ func (p *PoolWithFunc) getWorker() *WorkerWithFunc { } else if w == nil { w = &WorkerWithFunc{ pool: p, - args: make(chan interface{}, 1), + args: make(chan interface{}, workerChanCap), } w.run() p.incRunning()