]> git.feebdaed.xyz Git - 0xmirror/quic-go.git/commitdiff
ackhandler: add a benchmark for sending and acknowledging packets (#5333)
authorMarten Seemann <martenseemann@gmail.com>
Sun, 14 Sep 2025 05:00:13 +0000 (13:00 +0800)
committerGitHub <noreply@github.com>
Sun, 14 Sep 2025 05:00:13 +0000 (07:00 +0200)
* ackhandler: add a benchmark for sending and acknowledging packets

* report allocs, improve benchmark names

internal/ackhandler/sent_packet_handler_test.go

index 13dcdc0b850d35aa2814df916cb662ffd13212f4..d02be74f362688797aacd2be5beb411514897014 100644 (file)
@@ -61,13 +61,16 @@ func (h *sentPacketHandler) getBytesInFlight() protocol.ByteCount {
 }
 
 func ackRanges(pns ...protocol.PacketNumber) []wire.AckRange {
+       return appendAckRanges(nil, pns...)
+}
+
+func appendAckRanges(ranges []wire.AckRange, pns ...protocol.PacketNumber) []wire.AckRange {
        if len(pns) == 0 {
-               return nil
+               return ranges
        }
        slices.Sort(pns)
        slices.Reverse(pns)
 
-       var ranges []wire.AckRange
        start := pns[0]
        for i := 1; i < len(pns); i++ {
                if pns[i-1]-pns[i] > 1 {
@@ -1339,3 +1342,69 @@ func testSentPacketHandlerRandomized(t *testing.T, seed uint64) {
        t.Logf("t=%dms: loss detection timeout (lost: %v)", now.Sub(start).Milliseconds(), packets.Lost)
        sph.OnLossDetectionTimeout(now)
 }
+
+func BenchmarkSendAndAcknowledge(b *testing.B) {
+       b.Run("ack every: 2, in flight: 0", func(b *testing.B) {
+               benchmarkSendAndAcknowledge(b, 2, 0)
+       })
+       b.Run("ack every: 10, in flight: 100", func(b *testing.B) {
+               benchmarkSendAndAcknowledge(b, 10, 100)
+       })
+       b.Run("ack every: 100, in flight: 1000", func(b *testing.B) {
+               benchmarkSendAndAcknowledge(b, 100, 1000)
+       })
+}
+
+func benchmarkSendAndAcknowledge(b *testing.B, ackEvery, inFlight int) {
+       b.ReportAllocs()
+
+       var rttStats utils.RTTStats
+       sph := newSentPacketHandler(
+               0,
+               1200,
+               &rttStats,
+               &utils.ConnectionStats{},
+               true,
+               false,
+               protocol.PerspectiveClient,
+               nil,
+               utils.DefaultLogger,
+       )
+       now := time.Now()
+       sph.DropPackets(protocol.EncryptionInitial, now)
+       sph.DropPackets(protocol.EncryptionHandshake, now)
+
+       streamFrames := []StreamFrame{{Frame: &wire.StreamFrame{}}}
+
+       pns := make([]protocol.PacketNumber, 0, ackEvery+inFlight)
+
+       var counter int
+       ranges := make([]wire.AckRange, 0, ackEvery)
+       for b.Loop() {
+               counter++
+               pn := sph.PopPacketNumber(protocol.Encryption1RTT)
+               sph.SentPacket(
+                       now,
+                       pn,
+                       protocol.InvalidPacketNumber,
+                       streamFrames,
+                       nil,
+                       protocol.Encryption1RTT,
+                       protocol.ECNNon,
+                       1200,
+                       false, false,
+               )
+               now = now.Add(time.Millisecond)
+               pns = append(pns, pn)
+
+               if counter > inFlight && counter%ackEvery == 0 {
+                       sph.ReceivedAck(
+                               &wire.AckFrame{AckRanges: appendAckRanges(ranges, pns[:ackEvery]...)},
+                               protocol.Encryption1RTT,
+                               now,
+                       )
+                       pns = append(pns[:0], pns[ackEvery:]...)
+                       ranges = ranges[:0]
+               }
+       }
+}