Skip to content

Commit d625f6f

Browse files
jechSean-Der
authored andcommitted
Optimise mux.dispatch
Uncurry the function MuxRange and avoid allocating a reader in isRTCP. The included benchmark indicates that we avoid five allocations per packet.
1 parent 7d97c9b commit d625f6f

File tree

2 files changed

+35
-25
lines changed

2 files changed

+35
-25
lines changed

internal/mux/mux_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,29 @@ func TestNonFatalRead(t *testing.T) {
142142
assert.NoError(t, m.Close())
143143
assert.NoError(t, ca.Close())
144144
}
145+
146+
func BenchmarkDispatch(b *testing.B) {
147+
m := &Mux{
148+
endpoints: make(map[*Endpoint]MatchFunc),
149+
log: logging.NewDefaultLoggerFactory().NewLogger("mux"),
150+
}
151+
152+
e := m.NewEndpoint(MatchSRTP)
153+
m.NewEndpoint(MatchSRTCP)
154+
155+
buf := []byte{128, 1, 2, 3, 4}
156+
buf2 := make([]byte, 1200)
157+
158+
b.StartTimer()
159+
160+
for i := 0; i < b.N; i++ {
161+
err := m.dispatch(buf)
162+
if err != nil {
163+
b.Errorf("dispatch: %v", err)
164+
}
165+
_, err = e.buffer.Read(buf2)
166+
if err != nil {
167+
b.Errorf("read: %v", err)
168+
}
169+
}
170+
}

internal/mux/muxfunc.go

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package mux
22

3-
import (
4-
"bytes"
5-
"encoding/binary"
6-
)
7-
83
// MatchFunc allows custom logic for mapping packets to an Endpoint
94
type MatchFunc func([]byte) bool
105

@@ -13,15 +8,13 @@ func MatchAll(b []byte) bool {
138
return true
149
}
1510

16-
// MatchRange is a MatchFunc that accepts packets with the first byte in [lower..upper]
17-
func MatchRange(lower, upper byte) MatchFunc {
18-
return func(buf []byte) bool {
19-
if len(buf) < 1 {
20-
return false
21-
}
22-
b := buf[0]
23-
return b >= lower && b <= upper
11+
// MatchRange returns true if the first byte of buf is in [lower..upper]
12+
func MatchRange(lower, upper byte, buf []byte) bool {
13+
if len(buf) < 1 {
14+
return false
2415
}
16+
b := buf[0]
17+
return b >= lower && b <= upper
2518
}
2619

2720
// MatchFuncs as described in RFC7983
@@ -41,30 +34,21 @@ func MatchRange(lower, upper byte) MatchFunc {
4134
// MatchDTLS is a MatchFunc that accepts packets with the first byte in [20..63]
4235
// as defied in RFC7983
4336
func MatchDTLS(b []byte) bool {
44-
return MatchRange(20, 63)(b)
37+
return MatchRange(20, 63, b)
4538
}
4639

4740
// MatchSRTPOrSRTCP is a MatchFunc that accepts packets with the first byte in [128..191]
4841
// as defied in RFC7983
4942
func MatchSRTPOrSRTCP(b []byte) bool {
50-
return MatchRange(128, 191)(b)
43+
return MatchRange(128, 191, b)
5144
}
5245

5346
func isRTCP(buf []byte) bool {
5447
// Not long enough to determine RTP/RTCP
5548
if len(buf) < 4 {
5649
return false
5750
}
58-
59-
var rtcpPacketType uint8
60-
r := bytes.NewReader([]byte{buf[1]})
61-
if err := binary.Read(r, binary.BigEndian, &rtcpPacketType); err != nil {
62-
return false
63-
} else if rtcpPacketType >= 192 && rtcpPacketType <= 223 {
64-
return true
65-
}
66-
67-
return false
51+
return buf[1] >= 192 && buf[1] <= 223
6852
}
6953

7054
// MatchSRTP is a MatchFunc that only matches SRTP and not SRTCP

0 commit comments

Comments
 (0)