wire: optimize parsing logic for STREAM, DATAGRAM and ACK frames (#5227)

ParseOtherFrames-16       148ns ± 4%     150ns ± 3%     ~     (p=0.223 n=8+8)
ParseAckFrame-16          302ns ± 2%     298ns ± 3%     ~     (p=0.246 n=8+8)
ParseStreamFrame-16       262ns ± 3%     213ns ± 2%  -18.61%  (p=0.000 n=8+8)
ParseDatagramFrame-16     561ns ± 5%     547ns ± 4%     ~     (p=0.105 n=8+8)
This commit is contained in:
Jannis Seemann
2025-07-20 14:14:38 +03:00
committed by GitHub
parent 893a5941fb
commit c2e784aaf2
49 changed files with 1097 additions and 450 deletions

View File

@@ -2,6 +2,7 @@ package frames
import (
"fmt"
"io"
"github.com/quic-go/quic-go/internal/ackhandler"
"github.com/quic-go/quic-go/internal/protocol"
@@ -41,15 +42,32 @@ func Fuzz(data []byte) int {
var b []byte
for len(data) > 0 {
initialLen := len(data)
l, f, err := parser.ParseNext(data, encLevel, version)
frameType, l, err := parser.ParseType(data, encLevel)
if err != nil {
if err == io.EOF { // the last frame was a PADDING frame
continue
}
break
}
data = data[l:]
numFrames++
var f wire.Frame
switch {
case frameType.IsStreamFrameType():
f, l, err = parser.ParseStreamFrame(frameType, data, version)
case frameType == wire.FrameTypeAck || frameType == wire.FrameTypeAckECN:
f, l, err = parser.ParseAckFrame(frameType, data, encLevel, version)
case frameType == wire.FrameTypeDatagramNoLength || frameType == wire.FrameTypeDatagramWithLength:
f, l, err = parser.ParseDatagramFrame(frameType, data, version)
default:
f, l, err = parser.ParseLessCommonFrame(frameType, data, version)
}
if err != nil {
break
}
data = data[l:]
numFrames++
if f == nil { // PADDING frame
continue
}
wire.IsProbingFrame(f)
ackhandler.IsFrameAckEliciting(f)
// We accept empty STREAM frames, but we don't write them.