File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 55 "errors"
66 "io"
77 "os"
8+ "sync"
89)
910
1011// ioCopier is a stage that copies its stdin to a specified
@@ -15,6 +16,16 @@ type ioCopier struct {
1516 err error
1617}
1718
19+ // copyBufPool reuses 32KB buffers across io.CopyBuffer calls, avoiding
20+ // a fresh heap allocation per copy. This matters in high-throughput
21+ // pipelines where many ioCopier stages run concurrently.
22+ var copyBufPool = sync.Pool {
23+ New : func () any {
24+ b := make ([]byte , 32 * 1024 )
25+ return & b
26+ },
27+ }
28+
1829func newIOCopier (w io.WriteCloser ) * ioCopier {
1930 return & ioCopier {
2031 w : w ,
@@ -29,7 +40,9 @@ func (s *ioCopier) Name() string {
2940// This method always returns `nil, nil`.
3041func (s * ioCopier ) Start (_ context.Context , _ Env , r io.ReadCloser ) (io.ReadCloser , error ) {
3142 go func () {
32- _ , err := io .Copy (s .w , r )
43+ bp := copyBufPool .Get ().(* []byte )
44+ _ , err := io .CopyBuffer (s .w , r , * bp )
45+ copyBufPool .Put (bp )
3346 // We don't consider `ErrClosed` an error (FIXME: is this
3447 // correct?):
3548 if err != nil && ! errors .Is (err , os .ErrClosed ) {
You can’t perform that action at this time.
0 commit comments