diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-04-24 13:34:48 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-04-24 13:48:26 +0200 |
commit | 1966902403aa9a5cec19eb9c51f7a3f0f1d0e80c (patch) | |
tree | 7b1cf10b09c2e72356eff909f197e0399fcc259e /client | |
parent | 81f2d7edf115a20b49ce3dd14ea174eabc253f4f (diff) |
Re-use gzip writers
Diffstat (limited to 'client')
-rw-r--r-- | client/go/internal/vespa/document/http.go | 15 | ||||
-rw-r--r-- | client/go/internal/vespa/document/http_test.go | 23 |
2 files changed, 36 insertions, 2 deletions
diff --git a/client/go/internal/vespa/document/http.go b/client/go/internal/vespa/document/http.go index 0530144747a..877bcc5edce 100644 --- a/client/go/internal/vespa/document/http.go +++ b/client/go/internal/vespa/document/http.go @@ -11,6 +11,7 @@ import ( "net/url" "strconv" "strings" + "sync" "sync/atomic" "time" @@ -31,6 +32,7 @@ type Client struct { httpClients []countingHTTPClient now func() time.Time sendCount int32 + gzippers sync.Pool } // ClientOptions specifices the configuration options of a feed client. @@ -78,11 +80,13 @@ func NewClient(options ClientOptions, httpClients []util.HTTPClient) *Client { if nowFunc == nil { nowFunc = time.Now } - return &Client{ + c := &Client{ options: options, httpClients: countingClients, now: nowFunc, } + c.gzippers.New = func() any { return gzip.NewWriter(io.Discard) } + return c } func (c *Client) queryParams() url.Values { @@ -167,18 +171,25 @@ func (c *Client) leastBusyClient() *countingHTTPClient { return &leastBusy } +func (c *Client) gzipWriter(w io.Writer) *gzip.Writer { + gzipWriter := c.gzippers.Get().(*gzip.Writer) + gzipWriter.Reset(w) + return gzipWriter +} + func (c *Client) createRequest(method, url string, body []byte) (*http.Request, error) { var r io.Reader useGzip := c.options.Compression == CompressionGzip || (c.options.Compression == CompressionAuto && len(body) > 512) if useGzip { var buf bytes.Buffer - w := gzip.NewWriter(&buf) + w := c.gzipWriter(&buf) if _, err := w.Write(body); err != nil { return nil, err } if err := w.Close(); err != nil { return nil, err } + c.gzippers.Put(w) r = &buf } else { r = bytes.NewReader(body) diff --git a/client/go/internal/vespa/document/http_test.go b/client/go/internal/vespa/document/http_test.go index 314113c53be..f67368b5128 100644 --- a/client/go/internal/vespa/document/http_test.go +++ b/client/go/internal/vespa/document/http_test.go @@ -293,3 +293,26 @@ func TestClientFeedURL(t *testing.T) { } } } + +func benchmarkClientSend(b *testing.B, compression Compression, document Document) { + httpClient := mock.HTTPClient{} + client := NewClient(ClientOptions{ + Compression: compression, + BaseURL: "https://example.com:1337", + Timeout: time.Duration(5 * time.Second), + }, []util.HTTPClient{&httpClient}) + b.ResetTimer() // ignore setup + for n := 0; n < b.N; n++ { + client.Send(document) + } +} + +func BenchmarkClientSend(b *testing.B) { + doc := Document{Create: true, Id: mustParseId("id:ns:type::doc1"), Operation: OperationUpdate, Body: []byte(`{"fields":{"foo": "my document"}}`)} + benchmarkClientSend(b, CompressionNone, doc) +} + +func BenchmarkClientSendCompressed(b *testing.B) { + doc := Document{Create: true, Id: mustParseId("id:ns:type::doc1"), Operation: OperationUpdate, Body: []byte(`{"fields":{"foo": "my document"}}`)} + benchmarkClientSend(b, CompressionGzip, doc) +} |