1
2
3
4
5 package http2
6
7 import (
8 "testing"
9 )
10
11 func benchmarkThroughput(b *testing.B, wsFunc func() WriteScheduler, priority PriorityParam) {
12 const maxFrameSize = 16
13 const streamCount = 100
14
15 ws := wsFunc()
16 sc := &serverConn{maxFrameSize: maxFrameSize}
17 streams := make([]*stream, streamCount)
18
19
20 streamsFrame := [][]byte{
21 make([]byte, maxFrameSize*5),
22 make([]byte, maxFrameSize*10),
23 make([]byte, maxFrameSize*15),
24 make([]byte, maxFrameSize*20),
25 make([]byte, maxFrameSize*25),
26 }
27 for i := range streams {
28 streamID := uint32(i) + 1
29 streams[i] = &stream{
30 id: streamID,
31 sc: sc,
32 }
33 streams[i].flow.add(1 << 30)
34
35 ws.OpenStream(streamID, OpenStreamOptions{
36 priority: priority,
37 })
38 }
39
40 for b.Loop() {
41 for i := range streams {
42 streamID := uint32(i) + 1
43 ws.Push(FrameWriteRequest{
44 write: &writeData{
45 streamID: streamID,
46 p: streamsFrame[i%len(streamsFrame)],
47 endStream: false,
48 },
49 stream: streams[i],
50 })
51 }
52 for {
53 wr, ok := ws.Pop()
54 if !ok {
55 break
56 }
57 if wr.DataSize() != maxFrameSize {
58 b.Fatalf("wr.Pop() = %v data bytes, want %v", wr.DataSize(), maxFrameSize)
59 }
60 }
61 }
62
63 for i := range streams {
64 streamID := uint32(i) + 1
65 ws.CloseStream(streamID)
66 }
67 }
68
69 func benchmarkStreamLifetime(b *testing.B, wsFunc func() WriteScheduler, priority PriorityParam) {
70 const maxFrameSize = 16
71 const streamCount = 100
72
73 ws := wsFunc()
74 sc := &serverConn{maxFrameSize: maxFrameSize}
75 streams := make([]*stream, streamCount)
76
77
78 streamsFrame := [][]byte{
79 make([]byte, maxFrameSize*5),
80 make([]byte, maxFrameSize*10),
81 make([]byte, maxFrameSize*15),
82 make([]byte, maxFrameSize*20),
83 make([]byte, maxFrameSize*25),
84 }
85 for i := range streams {
86 streamID := uint32(i) + 1
87 streams[i] = &stream{
88 id: streamID,
89 sc: sc,
90 }
91 streams[i].flow.add(1 << 30)
92 }
93
94 for b.Loop() {
95 for i := range streams {
96 streamID := uint32(i) + 1
97 ws.OpenStream(streamID, OpenStreamOptions{
98 priority: priority,
99 })
100 ws.Push(FrameWriteRequest{
101 write: &writeData{
102 streamID: streamID,
103 p: streamsFrame[i%len(streamsFrame)],
104 endStream: false,
105 },
106 stream: streams[i],
107 })
108 }
109 for {
110 wr, ok := ws.Pop()
111 if !ok {
112 break
113 }
114 if wr.DataSize() != maxFrameSize {
115 b.Fatalf("wr.Pop() = %v data bytes, want %v", wr.DataSize(), maxFrameSize)
116 }
117 }
118 for i := range streams {
119 streamID := uint32(i) + 1
120 ws.CloseStream(streamID)
121 }
122 }
123
124 }
125
126 func BenchmarkWriteSchedulerThroughputRoundRobin(b *testing.B) {
127 benchmarkThroughput(b, newRoundRobinWriteScheduler, PriorityParam{})
128 }
129
130 func BenchmarkWriteSchedulerLifetimeRoundRobin(b *testing.B) {
131 benchmarkStreamLifetime(b, newRoundRobinWriteScheduler, PriorityParam{})
132 }
133
134 func BenchmarkWriteSchedulerThroughputPriorityRFC9218Incremental(b *testing.B) {
135 benchmarkThroughput(b, newPriorityWriteSchedulerRFC9218, PriorityParam{
136 incremental: 1,
137 })
138 }
139
140 func BenchmarkWriteSchedulerLifetimePriorityRFC9218Incremental(b *testing.B) {
141 benchmarkStreamLifetime(b, newPriorityWriteSchedulerRFC9218, PriorityParam{
142 incremental: 1,
143 })
144 }
145
146 func BenchmarkWriteSchedulerThroughputPriorityRFC9218NonIncremental(b *testing.B) {
147 benchmarkThroughput(b, newPriorityWriteSchedulerRFC9218, PriorityParam{
148 incremental: 0,
149 })
150 }
151
152 func BenchmarkWriteSchedulerLifetimePriorityRFC9218NonIncremental(b *testing.B) {
153 benchmarkStreamLifetime(b, newPriorityWriteSchedulerRFC9218, PriorityParam{
154 incremental: 0,
155 })
156 }
157
158 func BenchmarkWriteQueue(b *testing.B) {
159 var qp writeQueuePool
160 frameCount := 25
161 for b.Loop() {
162 q := qp.get()
163 for range frameCount {
164 q.push(FrameWriteRequest{})
165 }
166 for !q.empty() {
167
168
169 q.consume(1)
170 }
171 qp.put(q)
172 }
173 }
174
View as plain text