From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 22 Sep 2020 01:49:19 -0700 Subject: [PATCH] Optimise non-flush packet sending Original license: GPLv3 Original project: https://github.com/PaperMC/Paper Paper pull request: https://github.com/PaperMC/Paper/pull/10172 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. Co-authored-by: Quang Tran <3d7777456@gmail.com> diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java index 411e1284a208ca1a097cf6eaa92e1e0d2203d83d..ce7013f14f78b0d28806c91679cfe56f02998ee6 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -149,6 +149,7 @@ public class Connection extends SimpleChannelInboundHandler> { public @Nullable org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper // Paper start - Optimize network public boolean isPending = true; + private io.netty.channel.SingleThreadEventLoop eventLoop; // Paper - optimise packets that are not flushed public boolean queueImmunity; // Paper end - Optimize network @@ -160,6 +161,7 @@ public class Connection extends SimpleChannelInboundHandler> { public void channelActive(ChannelHandlerContext context) throws Exception { super.channelActive(context); this.channel = context.channel(); + this.eventLoop = (io.netty.channel.SingleThreadEventLoop) this.channel.eventLoop(); // Paper - optimise packets that are not flushed this.address = this.channel.remoteAddress(); this.preparing = false; // Spigot if (this.delayedDisconnect != null) { @@ -474,6 +476,11 @@ public class Connection extends SimpleChannelInboundHandler> { if (this.channel.eventLoop().inEventLoop()) { this.doSendPacket(packet, channelFutureListener, flag); } else { + // Paper start - optimise packets that are not flushed + if (!flag && org.dreeam.leaf.config.modules.network.OptimizeNonFlushPacketSending.enabled) { + this.eventLoop.lazyExecute(() -> this.doSendPacket(packet, channelFutureListener, flag)); + } else + // Paper end - optimise packets that are not flushed this.channel.eventLoop().execute(() -> this.doSendPacket(packet, channelFutureListener, flag)); } }