Skip to content

Commit

Permalink
Eliminate []byte(string) allocation under thrift transport
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua T Corbin committed Mar 29, 2019
1 parent 162ecb0 commit 223d473
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion thrift/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type readWriterTransport struct {
io.Reader
readBuf [1]byte
writeBuf [1]byte
strBuf []byte
}

var errNoBytesRead = errors.New("no bytes read")
Expand Down Expand Up @@ -82,7 +83,23 @@ func (t *readWriterTransport) WriteByte(b byte) error {
}

func (t *readWriterTransport) WriteString(s string) (int, error) {
return io.WriteString(t.Writer, s)
// TODO switch to io.StringWriter once we don't need to support < 1.12
type stringWriter interface{ WriteString(string) (int, error) }

if sw, ok := t.Writer.(stringWriter); ok {
return sw.WriteString(s)
}

// This path frequently taken since thrift.TBinaryProtocol calls
// WriteString a lot, but fragmentingWriter does not implement WriteString;
// furthermore it is difficult to add a dual WriteString path to
// fragmentingWriter, since hash checksumming does not accept strings.
//
// Without this, io.WriteString ends up allocating every time.
b := append(t.strBuf[:0], s...)
t.strBuf = b[:0]
return t.Writer.Write(b)

}

// RemainingBytes returns the max number of bytes (same as Thrift's StreamTransport) as we
Expand Down

0 comments on commit 223d473

Please sign in to comment.