1
0
mirror of https://github.com/golang/go synced 2024-11-23 20:30:04 -07:00

net/http: add request file upload benchmarks

This adds benchmarks to test file uploads using PUT requests.

It's designed to complement changes https://golang.org/cl/163599 and
https://golang.org/cl/163737, allowing an easy comparison of
performance before and after these changes are applied.

Updates #30377.

Co-authored-by: Emmanuel Odeke <emm.odeke@gmail.com>
This commit is contained in:
Chris Marchesi 2019-02-26 16:30:09 -08:00
parent 01f34cbf52
commit 242622b4fc
No known key found for this signature in database
GPG Key ID: 8D6F1589D9834498

View File

@ -8,12 +8,14 @@ import (
"bufio"
"bytes"
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
. "net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
@ -1046,3 +1048,92 @@ func BenchmarkReadRequestWrk(b *testing.B) {
Host: localhost:8080
`)
}
const (
withTLS = true
noTLS = false
)
func BenchmarkFileAndServer_1KB(b *testing.B) {
benchmarkFileAndServer(b, 1<<10)
}
func BenchmarkFileAndServer_16MB(b *testing.B) {
benchmarkFileAndServer(b, 1<<24)
}
func BenchmarkFileAndServer_64MB(b *testing.B) {
benchmarkFileAndServer(b, 1<<26)
}
func benchmarkFileAndServer(b *testing.B, n int64) {
f, err := ioutil.TempFile(os.TempDir(), "go-bench-http-file-and-server")
if err != nil {
b.Fatalf("Failed to create temp file: %v", err)
}
defer func() {
f.Close()
os.RemoveAll(f.Name())
}()
if _, err := io.CopyN(f, rand.Reader, n); err != nil {
b.Fatalf("Failed to copy %d bytes: %v", n, err)
}
b.Run("NoTLS", func(b *testing.B) {
runFileAndServerBenchmarks(b, noTLS, f, n)
})
b.Run("TLS", func(b *testing.B) {
runFileAndServerBenchmarks(b, withTLS, f, n)
})
}
func runFileAndServerBenchmarks(b *testing.B, tlsOption bool, f *os.File, n int64) {
handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
defer req.Body.Close()
nc, err := io.Copy(ioutil.Discard, req.Body)
if err != nil {
panic(err)
}
if nc != n {
panic(fmt.Errorf("Copied %d Wanted %d bytes", nc, n))
}
})
var cst *httptest.Server
if tlsOption == withTLS {
cst = httptest.NewTLSServer(handler)
} else {
cst = httptest.NewServer(handler)
}
defer cst.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
// Perform some setup.
b.StopTimer()
if _, err := f.Seek(0, 0); err != nil {
b.Fatalf("Failed to seek back to file: %v", err)
}
b.StartTimer()
req, err := NewRequest("PUT", cst.URL, ioutil.NopCloser(f))
if err != nil {
b.Fatal(err)
}
req.ContentLength = n
// Prevent mime sniffing by setting the Content-Type.
req.Header.Set("Content-Type", "application/octet-stream")
res, err := cst.Client().Do(req)
if err != nil {
b.Fatalf("Failed to make request to backend: %v", err)
}
res.Body.Close()
b.SetBytes(n)
}
}