-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbenchmark_test.go
111 lines (99 loc) · 2.25 KB
/
benchmark_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package request
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"reflect"
"strconv"
"testing"
"github.com/gorilla/mux"
)
type BenchReq struct {
State string `json:"state"`
User string `path:"user"`
Active bool `query:"active"`
Friends []string `query:"friend,explode"`
Delay int `header:"X-DELAY"`
}
var expected = BenchReq{
State: "active",
User: "adam",
Active: true,
Friends: []string{"bob", "steve"},
Delay: 60,
}
func BenchmarkDecode(b *testing.B) {
r := benchReq()
b.ResetTimer()
for n := 0; n < b.N; n++ {
var req BenchReq
err := Decode(r, &req)
if err != nil {
b.Fatal("failed to decode", err.Error())
}
if !reflect.DeepEqual(req, expected) {
b.Errorf("Decode(r, &req) = %v, want %v", req, expected)
}
// reset body
r.Body = io.NopCloser(bytes.NewReader([]byte(`{"state":"active"}`)))
}
}
func BenchmarkBaseline(b *testing.B) {
r := benchReq()
b.ResetTimer()
for n := 0; n < b.N; n++ {
req, err := baselineDecode(r)
if err != nil {
b.Fatal("failed to decode", err.Error())
}
if !reflect.DeepEqual(*req, expected) {
b.Errorf("baselineDecode(r) = %v, want %v", *req, expected)
}
// reset body
r.Body = io.NopCloser(bytes.NewReader([]byte(`{"state":"active"}`)))
}
}
func benchReq() *http.Request {
url := "/users/adam?active=true&friend=bob&friend=steve"
body := bytes.NewReader([]byte(`{"state":"active"}`))
r := httptest.NewRequest(http.MethodPut, url, body).WithContext(context.TODO())
r.Header.Set("X-Delay", "60")
r.Header.Set("Content-Type", "application/json")
vars := map[string]string{
"user": "adam",
}
r = mux.SetURLVars(r, vars)
return r
}
func baselineDecode(r *http.Request) (*BenchReq, error) {
query := r.URL.Query()
vars := mux.Vars(r)
active, err := strconv.ParseBool(query.Get("active"))
if err != nil {
return nil, err
}
delay, err := strconv.Atoi(r.Header.Get("X-DELAY"))
if err != nil {
return nil, err
}
friends := query["friend"]
b, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
defer r.Body.Close()
req := BenchReq{
User: vars["user"],
Active: active,
Delay: delay,
Friends: friends,
}
err = json.Unmarshal(b, &req)
if err != nil {
return nil, err
}
return &req, nil
}