1
2
3
4
5
6
7 package quic
8
9 import (
10 "context"
11 "fmt"
12 "io"
13 "math"
14 "sync"
15 "testing"
16 )
17
18
19 func BenchmarkThroughput(b *testing.B) {
20 for size := 1; size <= 64; size <<= 1 {
21 name := fmt.Sprintf("%dMiB", size)
22 b.Run(name, func(b *testing.B) {
23 throughput(b, int64(size<<20))
24 })
25 }
26 }
27
28 func throughput(b *testing.B, totalBytes int64) {
29
30 const bufsize = 32 << 10
31
32 cli, srv := newLocalConnPair(b, &Config{}, &Config{})
33
34 go func() {
35 buf := make([]byte, bufsize)
36 for i := 0; i < b.N; i++ {
37 sconn, err := srv.AcceptStream(context.Background())
38 if err != nil {
39 panic(fmt.Errorf("AcceptStream: %v", err))
40 }
41 if _, err := io.CopyBuffer(sconn, sconn, buf); err != nil {
42 panic(fmt.Errorf("CopyBuffer: %v", err))
43 }
44 sconn.Close()
45 }
46 }()
47
48 b.SetBytes(totalBytes)
49 buf := make([]byte, bufsize)
50 chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
51 for i := 0; i < b.N; i++ {
52 cconn, err := cli.NewStream(context.Background())
53 if err != nil {
54 b.Fatalf("NewStream: %v", err)
55 }
56 closec := make(chan struct{})
57 go func() {
58 defer close(closec)
59 buf := make([]byte, bufsize)
60 if _, err := io.CopyBuffer(io.Discard, cconn, buf); err != nil {
61 panic(fmt.Errorf("Discard: %v", err))
62 }
63 }()
64 for j := 0; j < chunks; j++ {
65 _, err := cconn.Write(buf)
66 if err != nil {
67 b.Fatalf("Write: %v", err)
68 }
69 }
70 cconn.CloseWrite()
71 <-closec
72 cconn.Close()
73 }
74 }
75
76 func BenchmarkReadByte(b *testing.B) {
77 cli, srv := newLocalConnPair(b, &Config{}, &Config{})
78
79 var wg sync.WaitGroup
80 defer wg.Wait()
81
82 wg.Add(1)
83 go func() {
84 defer wg.Done()
85 buf := make([]byte, 1<<20)
86 sconn, err := srv.AcceptStream(context.Background())
87 if err != nil {
88 panic(fmt.Errorf("AcceptStream: %v", err))
89 }
90 for {
91 if _, err := sconn.Write(buf); err != nil {
92 break
93 }
94 sconn.Flush()
95 }
96 }()
97
98 b.SetBytes(1)
99 cconn, err := cli.NewStream(context.Background())
100 if err != nil {
101 b.Fatalf("NewStream: %v", err)
102 }
103 cconn.Flush()
104 for i := 0; i < b.N; i++ {
105 _, err := cconn.ReadByte()
106 if err != nil {
107 b.Fatalf("ReadByte: %v", err)
108 }
109 }
110 cconn.Close()
111 }
112
113 func BenchmarkWriteByte(b *testing.B) {
114 cli, srv := newLocalConnPair(b, &Config{}, &Config{})
115
116 var wg sync.WaitGroup
117 defer wg.Wait()
118
119 wg.Add(1)
120 go func() {
121 defer wg.Done()
122 sconn, err := srv.AcceptStream(context.Background())
123 if err != nil {
124 panic(fmt.Errorf("AcceptStream: %v", err))
125 }
126 n, err := io.Copy(io.Discard, sconn)
127 if n != int64(b.N) || err != nil {
128 b.Errorf("server io.Copy() = %v, %v; want %v, nil", n, err, b.N)
129 }
130 }()
131
132 b.SetBytes(1)
133 cconn, err := cli.NewStream(context.Background())
134 if err != nil {
135 b.Fatalf("NewStream: %v", err)
136 }
137 cconn.Flush()
138 for i := 0; i < b.N; i++ {
139 if err := cconn.WriteByte(0); err != nil {
140 b.Fatalf("WriteByte: %v", err)
141 }
142 }
143 cconn.Close()
144 }
145
146 func BenchmarkStreamCreation(b *testing.B) {
147 cli, srv := newLocalConnPair(b, &Config{}, &Config{})
148
149 go func() {
150 for i := 0; i < b.N; i++ {
151 sconn, err := srv.AcceptStream(context.Background())
152 if err != nil {
153 panic(fmt.Errorf("AcceptStream: %v", err))
154 }
155 sconn.Close()
156 }
157 }()
158
159 buf := make([]byte, 1)
160 for i := 0; i < b.N; i++ {
161 cconn, err := cli.NewStream(context.Background())
162 if err != nil {
163 b.Fatalf("NewStream: %v", err)
164 }
165 cconn.Write(buf)
166 cconn.Flush()
167 cconn.Read(buf)
168 cconn.Close()
169 }
170 }
171
View as plain text