feat(Core/Optimization): Correctly document sendBuffer size and optimize it. (#18647)
* Fix comment documenting WorldSocket The buffer is constructed with 4096 bytes but later resized in WorldSocketThread::SocketAdded() according to the configuration setting Network.OutUBuff (currently 65536 bytes) * Reuse calculated packet size Instead of recalculating the current packet size three times at worst, calculate it once and reuse it when required. * Reduce reserved buffer size per WorldSocket Don't reserve 64kB of memory for every WorldSocket's output buffer. Instead, start with a 4kB baseline for every WorldSocket and grow the buffer size dynamically when we have single packets that do not fit the current buffer.
This commit is contained in:
@@ -364,11 +364,11 @@ Network.OutKBuff = -1
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Network.OutUBuff
|
# Network.OutUBuff
|
||||||
# Description: Amount of memory (in bytes) reserved in the user space per connection for
|
# Description: Amount of memory (in bytes) reserved initially in the user space per
|
||||||
# output buffering.
|
# connection for output buffering.
|
||||||
# Default: 65536
|
# Default: 4096
|
||||||
|
|
||||||
Network.OutUBuff = 65536
|
Network.OutUBuff = 4096
|
||||||
|
|
||||||
#
|
#
|
||||||
# Network.TcpNoDelay:
|
# Network.TcpNoDelay:
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ bool WorldSocket::Update()
|
|||||||
{
|
{
|
||||||
// Allocate buffer only when it's needed but not on every Update() call.
|
// Allocate buffer only when it's needed but not on every Update() call.
|
||||||
MessageBuffer buffer(_sendBufferSize);
|
MessageBuffer buffer(_sendBufferSize);
|
||||||
|
std::size_t currentPacketSize;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
queued->CompressIfNeeded();
|
queued->CompressIfNeeded();
|
||||||
@@ -172,26 +173,32 @@ bool WorldSocket::Update()
|
|||||||
if (queued->NeedsEncryption())
|
if (queued->NeedsEncryption())
|
||||||
_authCrypt.EncryptSend(header.header, header.getHeaderLength());
|
_authCrypt.EncryptSend(header.header, header.getHeaderLength());
|
||||||
|
|
||||||
if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength())
|
currentPacketSize = queued->size() + header.getHeaderLength();
|
||||||
|
|
||||||
|
if (buffer.GetRemainingSpace() < currentPacketSize)
|
||||||
{
|
{
|
||||||
QueuePacket(std::move(buffer));
|
QueuePacket(std::move(buffer));
|
||||||
buffer.Resize(_sendBufferSize);
|
buffer.Resize(_sendBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength())
|
if (buffer.GetRemainingSpace() >= currentPacketSize)
|
||||||
{
|
{
|
||||||
buffer.Write(header.header, header.getHeaderLength());
|
buffer.Write(header.header, header.getHeaderLength());
|
||||||
if (!queued->empty())
|
if (!queued->empty())
|
||||||
buffer.Write(queued->contents(), queued->size());
|
buffer.Write(queued->contents(), queued->size());
|
||||||
}
|
}
|
||||||
else // single packet larger than 4096 bytes
|
else // Single packet larger than current buffer size
|
||||||
{
|
{
|
||||||
MessageBuffer packetBuffer(queued->size() + header.getHeaderLength());
|
// Resize buffer to fit current packet
|
||||||
packetBuffer.Write(header.header, header.getHeaderLength());
|
buffer.Resize(currentPacketSize);
|
||||||
if (!queued->empty())
|
|
||||||
packetBuffer.Write(queued->contents(), queued->size());
|
|
||||||
|
|
||||||
QueuePacket(std::move(packetBuffer));
|
// Grow future buffers to current packet size if still below limit
|
||||||
|
if (currentPacketSize <= 65536)
|
||||||
|
_sendBufferSize = currentPacketSize;
|
||||||
|
|
||||||
|
buffer.Write(header.header, header.getHeaderLength());
|
||||||
|
if (!queued->empty())
|
||||||
|
buffer.Write(queued->contents(), queued->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete queued;
|
delete queued;
|
||||||
|
|||||||
Reference in New Issue
Block a user