-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
In #25383, a lock contention regression was brought up in ServeMux. I believe this lock contention is still present in the mux, and could be removed. Making ServeMux have an atomically loaded handler map can help reduce latency of serving at the cost of more expensive mutations.
A sample CL that fixes this regression is https://go-review.googlesource.com/c/go/+/149377 and shows promising speedups on the benchmarks:
$ benchstat /tmp/old.txt /tmp/new.txt
name old time/op new time/op delta
ServeMux-12 76.3µs ± 3% 64.0µs ± 7% -16.14% (p=0.000 n=30+30)
ServeMux_SkipServe-12 28.4µs ± 2% 19.8µs ± 3% -30.49% (p=0.000 n=28+28)
name old alloc/op new alloc/op delta
ServeMux-12 17.3kB ± 0% 17.3kB ± 0% ~ (all equal)
ServeMux_SkipServe-12 0.00B 0.00B ~ (all equal)
name old allocs/op new allocs/op delta
ServeMux-12 360 ± 0% 360 ± 0% ~ (all equal)
ServeMux_SkipServe-12 0.00 0.00 ~ (all equal)
However, this change depends on using CompareAndSwap, which is only available for unsafe.Pointer values. The reviewer of the CL expressed that using unsafe is unacceptable, though I am not really sure why. I have previously proposed that atomic.Value should gain these methods in #26728, but the proposal was also declined.
Options
Thus, there are a few ways forward that I can think of, but need a decision from the Go team:
- Accept the use of
unsafeinServeMux, and gain the extra efficiency. - Accept that there is a valid use case for
atomic.Value.CompareAndSwap(), and prioritize it being added as a public (or private) API, and use it instead. - Come up with some other solution to improve the serving speed of ServeMux, that is neither of the above two.
- Disagree that performance of the ServeMux matters or is worth optimizing, close the CL, and pay the extra 10us per request.
I feel rather helpless with regards to options 1 and 2. I have suggested both, but have received differing reasons for why they aren't acceptable from different Go team members. I'd rather the Go team just pick one of the 4 options above, because the requirements for changing Go are opaque from my POV.