-
Notifications
You must be signed in to change notification settings - Fork 230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GoPool's performance in comparison to other goroutine pool implementations #144
Comments
Could you please try the same test as https://github.com/bytedance/gopkg/blob/develop/util/gopool/pool_test.go? |
Got these results
https://github.com/alphadose/go-threadpool-benchmarks/blob/master/gopool_test.go |
Thanks for your tests! |
The first test was to mimic 1000s of HTTP requests each of which typically last within milliseconds, but yes there should be some computation and variance between requests for relation to an actual use case
if we remove the limit on itogami then it essentially becomes an infinite goroutine pool but it also saves a lot of memory (due to recycling via the stack) as compared to using native goroutines, hence I think its beneficial to use itogami in this case too with some modifications |
I think it's not enough to test cpu cost handler only, in most of the real scenarios, blocking is the much more usual operation than pure cpu cost, eg: http handler, rpc handler, and there is a write syscall at least. I tried with a short sleep and get a much worse performance from gopool than std: func testFunc() {
// DoCopyStack(0, 0)
time.Sleep(time.Microsecond * 10)
} result: BenchmarkPool-8 1 13349818686 ns/op 727840 B/op 20125 allocs/op
BenchmarkGo-8 82 13735426 ns/op 968846 B/op 20042 allocs/op This much worse result may be because the default pool size is only 8 in my env(runtime.GOMAXPROCS(0)==8). # pool size: 1000
BenchmarkPool-8 10 109975368 ns/op 466008 B/op 12162 allocs/op
BenchmarkGo-8 85 13984710 ns/op 970441 B/op 20082 allocs/op # pool size: 10000
BenchmarkPool-8 68 17622188 ns/op 1421435 B/op 30038 allocs/op
BenchmarkGo-8 86 14227710 ns/op 971272 B/op 20074 allocs/op |
@alphadose But indeed we need to limit the pool size to control the total memory cost of the process. |
@alphadose Cool! |
@alphadose And the same point with gopool's default cpu cost handler, if I limit the pool size and change to a testFunc with a short sleep, itogami doesn't perform better than std in my env: # pool size: 1000
BenchmarkPool-8 10 110218422 ns/op 461439 B/op 12138 allocs/op
BenchmarkGo-8 84 13746197 ns/op 969096 B/op 20052 allocs/op
BenchmarkItogami-8 10 104207091 ns/op 200136 B/op 10413 allocs/op It's only faster than std when the PoolSize >= benchmarkTimes or the blocking time is shorter than b.N calling loop cost, else it's worse than std.
It's no use if we don't limit the pool size and I think users prefer to use std goroutine rather than use another implementation like std. |
I met a goos: linux
goarch: amd64
pkg: github.com/alphadose/go-threadpool-benchmarks
cpu: Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
BenchmarkGo-8 328 3554240 ns/op 972669 B/op 20124 allocs/op
BenchmarkPool-8 206 6353972 ns/op 590759 B/op 19165 allocs/op
BenchmarkItogami-8 fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x330 pc=0x4372a7]
...... |
@lesismal I made itogami as a proof of concept for a better golang scheduler, and as it uses golang runtime internals it is unsafe because of some edge cases here and there. Hence, its also unsafe to use for real use cases. If you are interested here is the corresponding issue in golang core golang/go#53398 |
I took a quick look at 53398, It's good trying to use lock-free to optimize performance.
Since it's unsafe, the benchmark result should not be used to compare with std other goroutine pools, it doesn't make sense and would make misleading. About http performance, I agree with you that fasthttp is really fast, but gnet's http benchmark is not a fully implementation of http protocol, details here, that also makes misleading. I used to opend an issue to advise not to use that benchmark result to claim gnet's performance but wasn't accepted.. But I would still be glad to see if someday the author deletes the http benchmark result, or if he fully supports the protocol. I have another lib that does these tls/http/websocket things with goroutine num and memory usage under controlled: https://github.com/lesismal/nbio |
I went through the golang's scheduling code and there is room for improvement by switching to a lock-free stack in some places. I got the idea itself from a gophercon talk delivered by a member of golang core team and I tested it out, got some good results. The major performance improvement by switching to a lock free stack would be scheduling all operations entirely in user-space and avoid
Agreed, I will update the readme so that people are aware that its experimental and unsafe. |
Question
GoPool seems to perform poorly from the benchmarks I ran
Reference -> https://github.com/alphadose/itogami
Benchmarking code -> https://github.com/alphadose/go-threadpool-benchmarks
The text was updated successfully, but these errors were encountered: