| commit | e7c005de60f2d329656d852b863ea0a1302a600d | [log] [tgz] |
|---|---|---|
| author | Nicholas S. Husin <nsh@golang.org> | Thu Oct 09 02:10:40 2025 -0400 |
| committer | Nicholas Husin <nsh@golang.org> | Thu Oct 09 10:55:28 2025 -0700 |
| tree | 00f946d74182952194b6159c46c689e1bd8e5b70 | |
| parent | b93acc2126d5ad1a8836390a0fd801eb7dceb5b6 [diff] |
http2: implement a more efficient writeQueue that avoids unnecessary copies.
Our previous implementation of writeQueue relies on one
[]FrameWriteRequests, forcing us to copy the rest of the slice's content
whenever we remove an item from the front.
This change remedies this problem by implementing writeQueue using
two-stage queues, similar to Okasaki's purely functional queue.
With 25 frames per stream, we are observing the following performance
improvement:
goos: linux
goarch: amd64
pkg: golang.org/x/net/http2
cpu: AMD EPYC 7B13
│ /tmp/old │ /tmp/new │
│ sec/op │ sec/op vs base │
WriteQueue-64 508.3n ± 3% 305.7n ± 3% -39.86% (p=0.000 n=10)
│ /tmp/old │ /tmp/new │
│ B/op │ B/op vs base │
WriteQueue-64 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
¹ all samples are equal
│ /tmp/old │ /tmp/new │
│ allocs/op │ allocs/op vs base │
WriteQueue-64 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
¹ all samples are equal
As the number of frames increases, the performance difference becomes
more stark as the old implementation does a quadratic amount of copying
in total to be able to fully consume a queue.
Change-Id: Ide816ebdd89a41275b5829683c0f10d48321af50
Reviewed-on: https://go-review.googlesource.com/c/net/+/710635
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
This repository holds supplementary Go networking packages.
This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://go.dev/doc/contribute.
The git repository is https://go.googlesource.com/net.
The main issue tracker for the net repository is located at https://go.dev/issues. Prefix your issue with “x/net:” in the subject line, so it is easy to find.