Skip to content

Commit

Permalink
Added some new optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
Lora4967 committed Jan 28, 2024
1 parent a03519f commit ad71c13
Show file tree
Hide file tree
Showing 6 changed files with 383 additions and 0 deletions.
50 changes: 50 additions & 0 deletions patches/server/0054-Sparkly-Paper-Optimize-canSee-checks.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:51:56 +0000
Subject: [PATCH] Sparkly Paper Optimize canSee checks


diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 4709782f3e858edfa6ce25696462eb45909885ee..3cba356b74362c2fc010d0c1bfb6eeecb449908e 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1419,7 +1419,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Folia end - region threading

// CraftBukkit start - respect vanish API
- if (flag && (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading
+ if (flag && (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading // SparklyPaper - optimize canSee checks
flag = false;
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 06c92a2d3ecb3b747c2303819f72c1c41967af8c..7ae6925732c347ec97c94c5fdfd0012fbe6820fc 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -183,7 +183,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private boolean hasPlayedBefore = false;
private final ConversationTracker conversationTracker = new ConversationTracker();
private final Set<String> channels = new HashSet<String>();
- private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>();
+ private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // SparklyPaper - optimize canSee checks
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
private int hash = 0;
@@ -2075,9 +2075,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {

@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
- return this.equals(entity) || entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()); // SPIGOT-7312: Can always see self
+ return this.equals(entity) || entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // SparklyPaper - optimize canSee checks
}

+ // SparklyPaper - optimize canSee checks
+ // The check in ChunkMap#updatePlayer already rejects if it is the same entity, so we don't need to check it twice, especially because CraftPlayer's equals check is a bit expensive
+ public boolean canSeeChunkMapUpdatePlayer(org.bukkit.entity.Entity entity) {
+ return entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // SparklyPaper - optimize canSee checks
+ }
+ // SparklyPaper end
+
public boolean canSee(UUID uuid) {
org.bukkit.entity.Entity entity = this.getServer().getPlayer(uuid);
if (entity == null) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:52:09 +0000
Subject: [PATCH] Gale Skip entity move if movement is zero


diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 18fdb265714584d4ee759d86cc8a10b13742e153..ec255db477e6308cc0fbe336b7bebeac75b97b2a 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -317,6 +317,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
public float yRotO;
public float xRotO;
private AABB bb;
+ private boolean boundingBoxChanged = false; // Gale - VMP - skip entity move if movement is zero
public boolean onGround;
public boolean horizontalCollision;
public boolean verticalCollision;
@@ -1090,6 +1091,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
//Luminol end

public void move(MoverType movementType, Vec3 movement) {
+ // Gale start - VMP - skip entity move if movement is zero
+ if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) {
+ return;
+ }
+ // Gale end - VMP - skip entity move if movement is zero
// Paper start - detailed watchdog information
io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main");
//Luminol start - Fix high position moving
@@ -4875,6 +4881,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}

public final void setBoundingBox(AABB boundingBox) {
+ // Gale start - VMP - skip entity move if movement is zero
+ if (!this.bb.equals(boundingBox)) {
+ this.boundingBoxChanged = true;
+ }
+ // Gale end - VMP - skip entity move if movement is zero
// CraftBukkit start - block invalid bounding boxes
double minX = boundingBox.minX,
minY = boundingBox.minY,
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:52:24 +0000
Subject: [PATCH] Gale Check frozen ticks before landing block


diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index ecbacbed29af51d949122b21c3ae9fc95885c6d8..3c83ff19c40eb44eae3ed9f7db4f5291d080b32c 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -591,11 +591,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
}

protected void tryAddFrost() {
- if (!this.getBlockStateOnLegacy().isAir()) {
int i = this.getTicksFrozen();

if (i > 0) {
- AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED);
+ AttributeInstance attributemodifiable = this.getBlockStateOnLegacy().isAir() ? null : this.getAttribute(Attributes.MOVEMENT_SPEED); // Gale - Lithium - check frozen ticks before landing block

if (attributemodifiable == null) {
return;
@@ -605,7 +604,6 @@ public abstract class LivingEntity extends Entity implements Attackable {

attributemodifiable.addTransientModifier(new AttributeModifier(LivingEntity.SPEED_MODIFIER_POWDER_SNOW_UUID, "Powder snow slow", (double) f, AttributeModifier.Operation.ADDITION));
}
- }

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:52:48 +0000
Subject: [PATCH] Gale Don't trigger lootable refresh for non-player
interaction


diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
index 02364a148b347e3669275553004391e31d77c0b5..6c6ed0e9877c7e0c9804f3c2c786a61c301e318f 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
@@ -70,6 +70,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
}

public void unpackLootTable(@Nullable Player player) {
+ if (player == null) return; // Gale - EMC - don't trigger lootable refresh for non-player interaction
if (this.level != null && this.lootableData.shouldReplenish(player) && this.level.getServer() != null) { // Paper - don't unpack loot table if not in world
LootTable lootTable = this.level.getServer().getLootData().getLootTable(this.lootTable);
if (player instanceof ServerPlayer) {
187 changes: 187 additions & 0 deletions patches/server/0058-Gale-Use-platform-math-functions.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:31:27 +0000
Subject: [PATCH] Gale Use platform math functions

License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
Gale - https://galemc.org

This patch is based on the following patch:
"Use Math.floor instead of fastfloor"
By: Xymb <xymb@endcrystal.me>
As part of: Kaiiju (https://github.com/KaiijuMC/Kaiiju)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)

* Comparison of floor methods used in Paper *

Measure shown is floored number of milliseconds
(nanoseconds integer-divided by 1_000_000
taken to get the floor of 1000 randomly chosen doubles
(all in the range of [-Integer.MAX_VALUE + 10, Integer.MAX_VALUE - 10])
100_000 times (making it 100_000_000 floor operations total)
and adding it to a total.

We are testing the following methods:
* net.minecraft.util.Mth.floor
* java.lang.Math.floor
* java.lang.StrictMath.floor
* org.apache.commons.math3.util.FastMath.floor
* org.apache.commons.math3.util.FastMath.floor, but with a hot start (see comment in code)
* io.papermc.paper.util.MCUtil.fastFloor

The tests performed clearly show that Math.floor is the fastest.
This is most likely due to java.lang.Math's usage of the @IntrinsicCandidate
annotation, which allows the JVM to use a more optimized implementation at runtime.
However, in the case that there is no intrinsic replacement for Math.floor,
it defers to StrictMath.floor, which relies on a number of native methods, and is
still much faster than the existing Minecraft utility functions.
Therefore, using Math.floor instead of these functions is better regardless.
In Apache Commons Math 4, FastMath.floor has also been removed in favor of Math.floor.

The versions used:
* Windows 10 Home 21H2 19044.3086
* OpenJDK Runtime Environment Temurin-19.0.2+7 (build 19.0.2+7)
* Paper a3c760e6af1e8c7244ef75c6da6e6df278a79e14 on Minecraft 1.20.1
* Apache Commons Math 3.6.1

Results:
Total is of type int Total is of type double
----------------------------------------------------------------------------------
Mth.floor 2113 (double) Mth.floor 2658
(int) Math.floor 130 Math.floor 194
(int) StrictMath.floor 835 StrictMath.floor 381
(int) FastMath.floor 412 FastMath.floor 376
(int) FastMath.floor with hot start 359 FastMath.floor with hot start 321
MCUtil.fastFloor 2284 (double) MCUtil.fastFloor 2469

Code is below:
```java
package somepackage;

import io.papermc.paper.util.MCUtil;
import net.minecraft.util.Mth;

import java.util.Random;

public class Main {

public static void main(String[] args) {

// IF FastMath.floor with a hot start:
// FastMath.floor(37485.5);

var random = new Random(4889338);
int size = 1000;
var values = new double[size];
double bound = Integer.MAX_VALUE - 10;
for (int i = 0; i < size; i++) {
values[i] = random.nextDouble(bound * 2) - bound;
}
int repeats = 100_000;

// int total = 0;
// OR
// double total = 0;

long start = System.nanoTime();
for (int repeat = 0; repeat < repeats; repeat++) {
for (int index = 0; index < size; index++) {
total += insert_function_being_tested_here(values[index]);
}
}
long diff = System.nanoTime() - start;
System.out.println(total);
System.out.println(diff / 1_000_000L);

}

}
```

diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
index a149d98be7b4744f18d4ed4940881e13a76e4a7c..ad61afcfe1d0b01b17bc02977e8ff2b8d0420088 100644
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -166,13 +166,11 @@ public final class MCUtil {
}

public static int fastFloor(double x) {
- int truncated = (int)x;
- return x < (double)truncated ? truncated - 1 : truncated;
+ return (int) Math.floor(x); // Gale - use platform math functions
}

public static int fastFloor(float x) {
- int truncated = (int)x;
- return x < (double)truncated ? truncated - 1 : truncated;
+ return (int) Math.floor(x); // Gale - use platform math functions
}

public static float normalizeYaw(float f) {
@@ -233,11 +231,11 @@ public final class MCUtil {
}

public static int getChunkCoordinate(final double coordinate) {
- return MCUtil.fastFloor(coordinate) >> 4;
+ return ((int) Math.floor(coordinate)) >> 4; // Gale - use platform math functions
}

public static int getBlockCoordinate(final double coordinate) {
- return MCUtil.fastFloor(coordinate);
+ return (int) Math.floor(coordinate); // Gale - use platform math functions
}

public static long getBlockKey(final int x, final int y, final int z) {
diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java
index 33ace08d15bbcad66c09c7bd65dd03e784246e8f..d04586223a9b2a30efb17da01fb7f3e8f2a6af7b 100644
--- a/src/main/java/net/minecraft/util/Mth.java
+++ b/src/main/java/net/minecraft/util/Mth.java
@@ -51,13 +51,11 @@ public class Mth {
}

public static int floor(float value) {
- int i = (int)value;
- return value < (float)i ? i - 1 : i;
+ return (int) Math.floor(value); // Gale - use platform math functions
}

public static int floor(double value) {
- int i = (int)value;
- return value < (double)i ? i - 1 : i;
+ return (int) Math.floor(value); // Gale - use platform math functions
}

public static long lfloor(double value) {
@@ -74,13 +72,11 @@ public class Mth {
}

public static int ceil(float value) {
- int i = (int)value;
- return value > (float)i ? i + 1 : i;
+ return (int) Math.ceil(value); // Gale - use platform math functions
}

public static int ceil(double value) {
- int i = (int)value;
- return value > (double)i ? i + 1 : i;
+ return (int) Math.ceil(value); // Gale - use platform math functions
}

public static int clamp(int value, int min, int max) {
@@ -116,15 +112,7 @@ public class Mth {
}

public static double absMax(double a, double b) {
- if (a < 0.0D) {
- a = -a;
- }
-
- if (b < 0.0D) {
- b = -b;
- }
-
- return Math.max(a, b);
+ return Math.max(Math.abs(a), Math.abs(b)); // Gale - use platform math functions
}

public static int floorDiv(int dividend, int divisor) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Sun, 28 Jan 2024 09:31:27 +0000
Subject: [PATCH] Gale Faster floating-point positive modulo

License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
Gale - https://galemc.org

diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java
index d04586223a9b2a30efb17da01fb7f3e8f2a6af7b..bae83b708cafb867f43d5378fa78818fc382e2fa 100644
--- a/src/main/java/net/minecraft/util/Mth.java
+++ b/src/main/java/net/minecraft/util/Mth.java
@@ -143,14 +143,26 @@ public class Mth {
return Math.floorMod(dividend, divisor);
}

- public static float positiveModulo(float dividend, float divisor) {
+ public static float positiveModuloForAnyDivisor(float dividend, float divisor) { // Gale - faster floating-point positive modulo
return (dividend % divisor + divisor) % divisor;
}

- public static double positiveModulo(double dividend, double divisor) {
+ public static double positiveModuloForAnyDivisor(double dividend, double divisor) { // Gale - faster floating-point positive modulo
return (dividend % divisor + divisor) % divisor;
}

+ // Gale start - faster floating-point positive modulo
+ public static float positiveModuloForPositiveIntegerDivisor(float dividend, float divisor) {
+ var modulo = dividend % divisor;
+ return modulo < 0 ? modulo + divisor : modulo;
+ }
+
+ public static double positiveModuloForPositiveIntegerDivisor(double dividend, double divisor) {
+ var modulo = dividend % divisor;
+ return modulo < 0 ? modulo + divisor : modulo;
+ }
+ // Gale end - faster floating-point positive modulo
+
public static boolean isMultipleOf(int a, int b) {
return a % b == 0;
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/blending/Blender.java b/src/main/java/net/minecraft/world/level/levelgen/blending/Blender.java
index 8d40205f56a7b204a65505f9e1b4e20000221755..fe4a27e9e8265fc60e1db6dd070f91b212904e30 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/blending/Blender.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/blending/Blender.java
@@ -139,7 +139,7 @@ public class Blender {
private static double heightToOffset(double height) {
double d = 1.0D;
double e = height + 0.5D;
- double f = Mth.positiveModulo(e, 8.0D);
+ double f = Mth.positiveModuloForPositiveIntegerDivisor(e, 8.0D); // Gale - faster floating-point positive modulo
return 1.0D * (32.0D * (e - 128.0D) - 3.0D * (e - 120.0D) * f + 3.0D * f * f) / (128.0D * (32.0D - 3.0D * f));
}

0 comments on commit ad71c13

Please sign in to comment.