forked from quic-go/quic-go
use a sync.Pool to reduce allocation of linked list elements
Especially the sentPacketHistory linked list shows up in allocation profiles, since a new list element is allocated for every single packet we send. Using a pool for the receiving path, as well as for the frame sorter, is less critical, since we're tracking ranges there instead of individual packets / frames, but it doesn't hurt either. The other occurrences where we use a linked list (connection ID tracking and the token store) are used so rarely (a few times over the lifetime of the connection) that using a pool doesn't make any sense there.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package ackhandler
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
list "github.com/lucas-clemente/quic-go/internal/utils/linkedlist"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
@@ -12,6 +14,12 @@ type interval struct {
|
||||
End protocol.PacketNumber
|
||||
}
|
||||
|
||||
var intervalElementPool sync.Pool
|
||||
|
||||
func init() {
|
||||
intervalElementPool = *list.NewPool[interval]()
|
||||
}
|
||||
|
||||
// The receivedPacketHistory stores if a packet number has already been received.
|
||||
// It generates ACK ranges which can be used to assemble an ACK frame.
|
||||
// It does not store packet contents.
|
||||
@@ -23,7 +31,7 @@ type receivedPacketHistory struct {
|
||||
|
||||
func newReceivedPacketHistory() *receivedPacketHistory {
|
||||
return &receivedPacketHistory{
|
||||
ranges: list.New[interval](),
|
||||
ranges: list.NewWithPool[interval](&intervalElementPool),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package ackhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
@@ -17,11 +18,17 @@ type sentPacketHistory struct {
|
||||
highestSent protocol.PacketNumber
|
||||
}
|
||||
|
||||
var packetElementPool sync.Pool
|
||||
|
||||
func init() {
|
||||
packetElementPool = *list.NewPool[*Packet]()
|
||||
}
|
||||
|
||||
func newSentPacketHistory(rttStats *utils.RTTStats) *sentPacketHistory {
|
||||
return &sentPacketHistory{
|
||||
rttStats: rttStats,
|
||||
outstandingPacketList: list.New[*Packet](),
|
||||
etcPacketList: list.New[*Packet](),
|
||||
outstandingPacketList: list.NewWithPool[*Packet](&packetElementPool),
|
||||
etcPacketList: list.NewWithPool[*Packet](&packetElementPool),
|
||||
packetMap: make(map[protocol.PacketNumber]*list.Element[*Packet]),
|
||||
highestSent: protocol.InvalidPacketNumber,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user