From c95273f973c7abfc7ab000c2e8888ce875db5b59 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 9 Sep 2015 20:48:46 -0400 Subject: [PATCH] Optimize Chunk Saving Memory Allocation and Compression Minecraft ineffeciently uses OutputStreams by calling .write(int) on the stream. For Chunks, this is a DeflaterOutputStream, which allocates a single byte EVERY write. This is causing the server to allocate tons of new byte[1] objects. Additionally, this is very ineffecient for the Deflate process. By Buffering Writes the same way it already is Buffering Reads, we will write to the stream much more effeciently. Also a more effecient RegionFile zero'ing for new chunks to speed up new chunk generation. --- .../0003-Skeleton-API-Implementations.patch | 2 +- ...dd-Getter-for-Entity-Invulnerability.patch | 2 +- ...121-Cross-World-Entity-Teleportation.patch | 2 +- ...aving-Memory-Allocation-and-Compress.patch | 33 +++++++++++++++ ...9-More-effecient-RegionFile-zero-ing.patch | 41 +++++++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 CraftBukkit-Patches/0158-Optimize-Chunk-Saving-Memory-Allocation-and-Compress.patch create mode 100644 CraftBukkit-Patches/0159-More-effecient-RegionFile-zero-ing.patch diff --git a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch index 1c1fbdf..651c15b 100644 --- a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch +++ b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch @@ -1,4 +1,4 @@ -From 0eee1e3cd7129692baef76a063c7a4e62100cf86 Mon Sep 17 00:00:00 2001 +From 6e6193c0e175991dcb0e464d39c193c9aa46f27e Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 15:10:56 +1000 Subject: [PATCH] Skeleton API Implementations diff --git a/CraftBukkit-Patches/0038-Add-Getter-for-Entity-Invulnerability.patch b/CraftBukkit-Patches/0038-Add-Getter-for-Entity-Invulnerability.patch index 2e3518d..209f730 100644 --- a/CraftBukkit-Patches/0038-Add-Getter-for-Entity-Invulnerability.patch +++ b/CraftBukkit-Patches/0038-Add-Getter-for-Entity-Invulnerability.patch @@ -1,4 +1,4 @@ -From 1b3a4837aebc2072d4229c6e2d34938342620063 Mon Sep 17 00:00:00 2001 +From af0d91f09d43929fbb2cc2e49892dd1065decb39 Mon Sep 17 00:00:00 2001 From: DerFlash Date: Sat, 3 Aug 2013 19:53:48 +1000 Subject: [PATCH] Add Getter for Entity Invulnerability diff --git a/CraftBukkit-Patches/0121-Cross-World-Entity-Teleportation.patch b/CraftBukkit-Patches/0121-Cross-World-Entity-Teleportation.patch index 16d358e..65ca397 100644 --- a/CraftBukkit-Patches/0121-Cross-World-Entity-Teleportation.patch +++ b/CraftBukkit-Patches/0121-Cross-World-Entity-Teleportation.patch @@ -1,4 +1,4 @@ -From c84e8b213d787358de30c456003e4abc570e9a32 Mon Sep 17 00:00:00 2001 +From 879e94cd8a3d63afc8defe693f08018b9a19f874 Mon Sep 17 00:00:00 2001 From: Andrew Krieger Date: Tue, 24 Dec 2013 07:55:23 -0800 Subject: [PATCH] Cross World Entity Teleportation diff --git a/CraftBukkit-Patches/0158-Optimize-Chunk-Saving-Memory-Allocation-and-Compress.patch b/CraftBukkit-Patches/0158-Optimize-Chunk-Saving-Memory-Allocation-and-Compress.patch new file mode 100644 index 0000000..02687f2 --- /dev/null +++ b/CraftBukkit-Patches/0158-Optimize-Chunk-Saving-Memory-Allocation-and-Compress.patch @@ -0,0 +1,33 @@ +From bec646b094570475d33dac9381e03b8ce6ba4286 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 29 Aug 2015 13:59:25 -0400 +Subject: [PATCH] Optimize Chunk Saving Memory Allocation and Compression + +Minecraft ineffeciently uses OutputStreams by calling .write(int) on the stream. +For Chunks, this is a DeflaterOutputStream, which allocates a single byte EVERY write. + +This is causing the server to allocate tons of new byte[1] objects. +Additionally, this is very ineffecient for the Deflate process. + +By Buffering Writes the same way it already is Buffering Reads, we will +write to the stream much more effeciently. + +diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java +index 3e31f4b..fe3fbb0 100644 +--- a/src/main/java/net/minecraft/server/RegionFile.java ++++ b/src/main/java/net/minecraft/server/RegionFile.java +@@ -176,8 +176,9 @@ public class RegionFile { + } + } + +- public DataOutputStream b(int i, int j) { +- return this.d(i, j) ? null : new DataOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(i, j))); ++ public DataOutputStream b(int i, int j) { // PAIL: getChunkOutputStream ++ // PAIL: isInvalidRegion ++ return this.d(i, j) ? null : new DataOutputStream(new java.io.BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(i, j)))); // Spigot - use a BufferedOutputStream to greatly improve file write performance + } + + protected synchronized void a(int i, int j, byte[] abyte, int k) { +-- +1.9.1 + diff --git a/CraftBukkit-Patches/0159-More-effecient-RegionFile-zero-ing.patch b/CraftBukkit-Patches/0159-More-effecient-RegionFile-zero-ing.patch new file mode 100644 index 0000000..ac655d6 --- /dev/null +++ b/CraftBukkit-Patches/0159-More-effecient-RegionFile-zero-ing.patch @@ -0,0 +1,41 @@ +From 0fe6a5f1ec7f039ee04368f5d974286b08ddb53f Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 29 Aug 2015 17:48:20 -0400 +Subject: [PATCH] More effecient RegionFile zero'ing + +Speeds up new Chunk Generation by using 2 4k block writes vs 2048 4 byte writes +more effecient than going in and out of native calls repeatedly. + +diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java +index fe3fbb0..348706f 100644 +--- a/src/main/java/net/minecraft/server/RegionFile.java ++++ b/src/main/java/net/minecraft/server/RegionFile.java +@@ -16,7 +16,7 @@ import java.util.zip.InflaterInputStream; + + public class RegionFile { + +- private static final byte[] a = new byte[4096]; ++ private static final byte[] a = new byte[4096]; // Spigot - note: if this ever changes to not be 4096 bytes, update constructor! // PAIL: empty 4k block + private final File b; + private RandomAccessFile c; + private final int[] d = new int[1024]; +@@ -38,13 +38,9 @@ public class RegionFile { + int i; + + if (this.c.length() < 4096L) { +- for (i = 0; i < 1024; ++i) { +- this.c.writeInt(0); +- } +- +- for (i = 0; i < 1024; ++i) { +- this.c.writeInt(0); +- } ++ // Spigot - more effecient chunk zero'ing ++ this.c.write(RegionFile.a); // Spigot ++ this.c.write(RegionFile.a); // Spigot + + this.g += 8192; + } +-- +1.9.1 +