Proposal Details
To write a data frame, the x/net/http2.Framer requires the data contents to first be accumulated into a single contiguous buffer. However, this is not always possible without requiring a copy. See this real-life example where a copy is required in order to construct the frame's contents before writing it. If we had an API like the following, this copy could be avoided:
func (f *Framer) WriteDataN(streamID uint32, endStream bool, data [][]byte) error
The implementation could be as simple as changing the append here into an append that loops over the slice of buffers instead of just the one buffer.
The gRPC code could then be changed to remove the copy and pass the 5-byte header buffer and the data buffer directly to the new method.
I'd also love to discuss other changes that could make the HTTP/2 Framer even more zero-copy friendly by transferring buffer ownership instead of using io.Reader/io.Writer, but the proposal above would be a simple step that provides real incremental performance.
cc @PapaCharlie, @atollena
Proposal Details
To write a data frame, the
x/net/http2.Framerrequires the data contents to first be accumulated into a single contiguous buffer. However, this is not always possible without requiring a copy. See this real-life example where a copy is required in order to construct the frame's contents before writing it. If we had an API like the following, this copy could be avoided:The implementation could be as simple as changing the append here into an append that loops over the slice of buffers instead of just the one buffer.
The gRPC code could then be changed to remove the copy and pass the 5-byte header buffer and the data buffer directly to the new method.
I'd also love to discuss other changes that could make the HTTP/2 Framer even more zero-copy friendly by transferring buffer ownership instead of using
io.Reader/io.Writer, but the proposal above would be a simple step that provides real incremental performance.cc @PapaCharlie, @atollena