papermc/patches/unapplied/server/0704-Optimise-non-flush-packet-sending.patch
2023-09-22 10:57:45 -07:00

46 lines
2.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 22 Sep 2020 01:49:19 -0700
Subject: [PATCH] Optimise non-flush packet sending
Places like entity tracking make heavy use of packet sending,
and internally netty will use some very expensive thread wakeup
calls when scheduling.
Thanks to various hacks in ProtocolLib as well as other
plugins, we cannot simply use a queue of packets to group
send on execute. We have to call execute for each packet.
Tux's suggestion here is exactly what was needed - tag
the Runnable indicating it should not make a wakeup call.
Big thanks to Tux for making this possible as I had given
up on this optimisation before he came along.
Locally this patch drops the entity tracker tick by a full 1.5x.
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 9a9924a645c71e0cec30e29a9defcd1e22e2e8ef..15798ed13488b8b8b16ebee557dce18e3dc51708 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -437,9 +437,19 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
if (this.channel.eventLoop().inEventLoop()) {
this.doSendPacket(packet, callbacks, enumprotocol, enumprotocol1, flush); // Paper
} else {
+ // Paper start - optimise packets that are not flushed
+ // note: since the type is not dynamic here, we need to actually copy the old executor code
+ // into two branches. On conflict, just re-copy - no changes were made inside the executor code.
+ if (!flush) {
+ io.netty.util.concurrent.AbstractEventExecutor.LazyRunnable run = () -> {
+ this.doSendPacket(packet, callbacks, enumprotocol, enumprotocol1, flush); // Paper - add flush parameter
+ };
+ this.channel.eventLoop().execute(run);
+ } else { // Paper end - optimise packets that are not flushed
this.channel.eventLoop().execute(() -> {
- this.doSendPacket(packet, callbacks, enumprotocol, enumprotocol1, flush); // Paper
+ this.doSendPacket(packet, callbacks, enumprotocol, enumprotocol1, flush); // Paper - add flush parameter // Paper - diff on change
});
+ } // Paper
}
}