Fix BlockState hashCode optimization patch performance bug

we missed something in updating this patch and accidently left
hashCode as a 0 value. This caused a pretty nasty performance hit
for BlockStateEnum instances as they would be all a hash collision.

This update fixes that and also promotes the optimizations to cover
ALL cases of Block States, not just enums.

While mojang cached hashCode in 1.13, we can still just use a simple
large prime based hashCode that auto increments guaranteeing no overlap.

Additionally, replace all equals with an identity check.
This commit is contained in:
Aikar 2019-02-28 01:35:06 -05:00
parent 906684ff4f
commit 2f8bdbfde8
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
2 changed files with 84 additions and 62 deletions

View file

@ -0,0 +1,84 @@
From 63f4233aa49d41ab53a84ebd6a20d8d10449855f Mon Sep 17 00:00:00 2001
From: Alfie Cleveland <alfeh@me.com>
Date: Fri, 19 Aug 2016 01:52:56 +0100
Subject: [PATCH] Optimise BlockState's hashCode/equals
These are singleton "single instance" objects. We can rely on
object identity checks safely.
Use a simpler optimized hashcode
diff --git a/src/main/java/net/minecraft/server/BlockState.java b/src/main/java/net/minecraft/server/BlockState.java
index d95c0955a9..ea0e0ff4fe 100644
--- a/src/main/java/net/minecraft/server/BlockState.java
+++ b/src/main/java/net/minecraft/server/BlockState.java
@@ -26,23 +26,13 @@ public abstract class BlockState<T extends Comparable<T>> implements IBlockState
}
public boolean equals(Object object) {
- if (this == object) {
- return true;
- } else if (!(object instanceof BlockState)) {
- return false;
- } else {
- BlockState<?> blockstate = (BlockState) object;
-
- return this.a.equals(blockstate.a) && this.b.equals(blockstate.b);
- }
+ return this == object; // Paper - only one instance per configuration
}
+ private static java.util.concurrent.atomic.AtomicInteger hashId = new java.util.concurrent.atomic.AtomicInteger(1);// Paper - only one instance per configuration
+ private final int hashCode = 92821 * hashId.getAndIncrement(); // Paper - only one instance per configuration
public final int hashCode() {
- if (this.c == null) {
- this.c = this.c();
- }
-
- return this.c;
+ return hashCode; // Paper - only one instance per configuration
}
public int c() {
diff --git a/src/main/java/net/minecraft/server/BlockStateBoolean.java b/src/main/java/net/minecraft/server/BlockStateBoolean.java
index 4c1d39d67c..71d2ad9703 100644
--- a/src/main/java/net/minecraft/server/BlockStateBoolean.java
+++ b/src/main/java/net/minecraft/server/BlockStateBoolean.java
@@ -28,7 +28,7 @@ public class BlockStateBoolean extends BlockState<Boolean> {
return obool.toString();
}
- public boolean equals(Object object) {
+ public boolean equals_unused(Object object) { // Paper
if (this == object) {
return true;
} else if (object instanceof BlockStateBoolean && super.equals(object)) {
diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java
index 986b9ccea8..facbf30b4e 100644
--- a/src/main/java/net/minecraft/server/BlockStateEnum.java
+++ b/src/main/java/net/minecraft/server/BlockStateEnum.java
@@ -47,7 +47,7 @@ public class BlockStateEnum<T extends Enum<T> & INamable> extends BlockState<T>
return ((INamable) t0).getName();
}
- public boolean equals(Object object) {
+ public boolean equals_unused(Object object) { // Paper
if (this == object) {
return true;
} else if (object instanceof BlockStateEnum && super.equals(object)) {
diff --git a/src/main/java/net/minecraft/server/BlockStateInteger.java b/src/main/java/net/minecraft/server/BlockStateInteger.java
index 2f12e15e07..613cd0bce2 100644
--- a/src/main/java/net/minecraft/server/BlockStateInteger.java
+++ b/src/main/java/net/minecraft/server/BlockStateInteger.java
@@ -37,7 +37,7 @@ public class BlockStateInteger extends BlockState<Integer> {
return this.a;
}
- public boolean equals(Object object) {
+ public boolean equals_unused(Object object) { // Paper
if (this == object) {
return true;
} else if (object instanceof BlockStateInteger && super.equals(object)) {
--
2.20.1

View file

@ -1,62 +0,0 @@
From 7064b8b9f50b18bbd81ed129577c4944104ad7d9 Mon Sep 17 00:00:00 2001
From: Alfie Cleveland <alfeh@me.com>
Date: Fri, 19 Aug 2016 01:52:56 +0100
Subject: [PATCH] Optimise BlockStateEnum hashCode and equals
diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java
index 986b9ccea..259da0aa0 100644
--- a/src/main/java/net/minecraft/server/BlockStateEnum.java
+++ b/src/main/java/net/minecraft/server/BlockStateEnum.java
@@ -9,6 +9,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -17,6 +18,11 @@ public class BlockStateEnum<T extends Enum<T> & INamable> extends BlockState<T>
private final ImmutableSet<T> a;
private final Map<String, T> b = Maps.newHashMap();
+ // Paper start - BlockStateEnum is a singleton, so we can use our own hashCode
+ private static AtomicInteger hashId = new AtomicInteger(1);
+ private int hashCode;
+ // Paper end
+
protected BlockStateEnum(String s, Class<T> oclass, Collection<T> collection) {
super(s, oclass);
this.a = ImmutableSet.copyOf(collection);
@@ -47,24 +53,14 @@ public class BlockStateEnum<T extends Enum<T> & INamable> extends BlockState<T>
return ((INamable) t0).getName();
}
+ @Override // Paper start - override equals as BlockStateEnum is a singleton
public boolean equals(Object object) {
- if (this == object) {
- return true;
- } else if (object instanceof BlockStateEnum && super.equals(object)) {
- BlockStateEnum<?> blockstateenum = (BlockStateEnum) object;
-
- return this.a.equals(blockstateenum.a) && this.b.equals(blockstateenum.b);
- } else {
- return false;
- }
+ return this == object;
+ // Paper end - override equals as BlockStateEnum is a singleton
}
public int c() {
- int i = super.c();
-
- i = 31 * i + this.a.hashCode();
- i = 31 * i + this.b.hashCode();
- return i;
+ return hashCode; // Paper - hashCode method is final, but we can do this here
}
public static <T extends Enum<T> & INamable> BlockStateEnum<T> of(String s, Class<T> oclass) {
--
2.20.1