Speedup BlockPos by fixing inlining

This commit is contained in:
Techcable 2016-01-29 03:26:31 -06:00 committed by Zach Brown
parent 972d71a30b
commit bb17101d59
2 changed files with 515 additions and 2 deletions

View file

@ -1,9 +1,100 @@
From ce5da7df48c5505249c2b932b66d5b45558c01c8 Mon Sep 17 00:00:00 2001
From ef451696bb6004f2d3467750038f2010f52a04b2 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com>
Date: Mon, 25 May 2015 15:37:00 -0500
Subject: [PATCH] mc-dev imports
diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
new file mode 100644
index 0000000..0b2277c
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
@@ -0,0 +1,85 @@
+package net.minecraft.server;
+
+import com.google.common.base.Objects;
+
+public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
+
+ public static final BaseBlockPosition ZERO = new BaseBlockPosition(0, 0, 0);
+ private final int a;
+ private final int c;
+ private final int d;
+
+ public BaseBlockPosition(int i, int j, int k) {
+ this.a = i;
+ this.c = j;
+ this.d = k;
+ }
+
+ public BaseBlockPosition(double d0, double d1, double d2) {
+ this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
+ }
+
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ } else if (!(object instanceof BaseBlockPosition)) {
+ return false;
+ } else {
+ BaseBlockPosition baseblockposition = (BaseBlockPosition) object;
+
+ return this.getX() != baseblockposition.getX() ? false : (this.getY() != baseblockposition.getY() ? false : this.getZ() == baseblockposition.getZ());
+ }
+ }
+
+ public int hashCode() {
+ return (this.getY() + this.getZ() * 31) * 31 + this.getX();
+ }
+
+ public int g(BaseBlockPosition baseblockposition) {
+ return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY();
+ }
+
+ public int getX() {
+ return this.a;
+ }
+
+ public int getY() {
+ return this.c;
+ }
+
+ public int getZ() {
+ return this.d;
+ }
+
+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
+ return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX());
+ }
+
+ public double c(double d0, double d1, double d2) {
+ double d3 = (double) this.getX() - d0;
+ double d4 = (double) this.getY() - d1;
+ double d5 = (double) this.getZ() - d2;
+
+ return d3 * d3 + d4 * d4 + d5 * d5;
+ }
+
+ public double d(double d0, double d1, double d2) {
+ double d3 = (double) this.getX() + 0.5D - d0;
+ double d4 = (double) this.getY() + 0.5D - d1;
+ double d5 = (double) this.getZ() + 0.5D - d2;
+
+ return d3 * d3 + d4 * d4 + d5 * d5;
+ }
+
+ public double i(BaseBlockPosition baseblockposition) {
+ return this.c((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ());
+ }
+
+ public String toString() {
+ return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
+ }
+
+ public int compareTo(Object object) {
+ return this.g((BaseBlockPosition) object);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
new file mode 100644
index 0000000..b1ae67a
@ -1529,6 +1620,272 @@ index 0000000..b610450
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
new file mode 100644
index 0000000..2bd5499
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -0,0 +1,260 @@
+package net.minecraft.server;
+
+import com.google.common.collect.AbstractIterator;
+import java.util.Iterator;
+
+public class BlockPosition extends BaseBlockPosition {
+
+ public static final BlockPosition ZERO = new BlockPosition(0, 0, 0);
+ private static final int c = 1 + MathHelper.c(MathHelper.b(30000000));
+ private static final int d = BlockPosition.c;
+ private static final int e = 64 - BlockPosition.c - BlockPosition.d;
+ private static final int f = 0 + BlockPosition.d;
+ private static final int g = BlockPosition.f + BlockPosition.e;
+ private static final long h = (1L << BlockPosition.c) - 1L;
+ private static final long i = (1L << BlockPosition.e) - 1L;
+ private static final long j = (1L << BlockPosition.d) - 1L;
+
+ public BlockPosition(int i, int j, int k) {
+ super(i, j, k);
+ }
+
+ public BlockPosition(double d0, double d1, double d2) {
+ super(d0, d1, d2);
+ }
+
+ public BlockPosition(Entity entity) {
+ this(entity.locX, entity.locY, entity.locZ);
+ }
+
+ public BlockPosition(Vec3D vec3d) {
+ this(vec3d.a, vec3d.b, vec3d.c);
+ }
+
+ public BlockPosition(BaseBlockPosition baseblockposition) {
+ this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
+ }
+
+ public BlockPosition a(double d0, double d1, double d2) {
+ return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2);
+ }
+
+ public BlockPosition a(int i, int j, int k) {
+ return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k);
+ }
+
+ public BlockPosition a(BaseBlockPosition baseblockposition) {
+ return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() + baseblockposition.getX(), this.getY() + baseblockposition.getY(), this.getZ() + baseblockposition.getZ());
+ }
+
+ public BlockPosition b(BaseBlockPosition baseblockposition) {
+ return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() - baseblockposition.getX(), this.getY() - baseblockposition.getY(), this.getZ() - baseblockposition.getZ());
+ }
+
+ public BlockPosition up() {
+ return this.up(1);
+ }
+
+ public BlockPosition up(int i) {
+ return this.shift(EnumDirection.UP, i);
+ }
+
+ public BlockPosition down() {
+ return this.down(1);
+ }
+
+ public BlockPosition down(int i) {
+ return this.shift(EnumDirection.DOWN, i);
+ }
+
+ public BlockPosition north() {
+ return this.north(1);
+ }
+
+ public BlockPosition north(int i) {
+ return this.shift(EnumDirection.NORTH, i);
+ }
+
+ public BlockPosition south() {
+ return this.south(1);
+ }
+
+ public BlockPosition south(int i) {
+ return this.shift(EnumDirection.SOUTH, i);
+ }
+
+ public BlockPosition west() {
+ return this.west(1);
+ }
+
+ public BlockPosition west(int i) {
+ return this.shift(EnumDirection.WEST, i);
+ }
+
+ public BlockPosition east() {
+ return this.east(1);
+ }
+
+ public BlockPosition east(int i) {
+ return this.shift(EnumDirection.EAST, i);
+ }
+
+ public BlockPosition shift(EnumDirection enumdirection) {
+ return this.shift(enumdirection, 1);
+ }
+
+ public BlockPosition shift(EnumDirection enumdirection, int i) {
+ return i == 0 ? this : new BlockPosition(this.getX() + enumdirection.getAdjacentX() * i, this.getY() + enumdirection.getAdjacentY() * i, this.getZ() + enumdirection.getAdjacentZ() * i);
+ }
+
+ public BlockPosition c(BaseBlockPosition baseblockposition) {
+ return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX());
+ }
+
+ public long asLong() {
+ return ((long) this.getX() & BlockPosition.h) << BlockPosition.g | ((long) this.getY() & BlockPosition.i) << BlockPosition.f | ((long) this.getZ() & BlockPosition.j) << 0;
+ }
+
+ public static BlockPosition fromLong(long i) {
+ int j = (int) (i << 64 - BlockPosition.g - BlockPosition.c >> 64 - BlockPosition.c);
+ int k = (int) (i << 64 - BlockPosition.f - BlockPosition.e >> 64 - BlockPosition.e);
+ int l = (int) (i << 64 - BlockPosition.d >> 64 - BlockPosition.d);
+
+ return new BlockPosition(j, k, l);
+ }
+
+ public static Iterable<BlockPosition> a(BlockPosition blockposition, BlockPosition blockposition1) {
+ final BlockPosition blockposition2 = new BlockPosition(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()));
+ final BlockPosition blockposition3 = new BlockPosition(Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ()));
+
+ return new Iterable() {
+ public Iterator<BlockPosition> iterator() {
+ return new AbstractIterator() {
+ private BlockPosition b = null;
+
+ protected BlockPosition a() {
+ if (this.b == null) {
+ this.b = blockposition;
+ return this.b;
+ } else if (this.b.equals(blockposition1)) {
+ return (BlockPosition) this.endOfData();
+ } else {
+ int i = this.b.getX();
+ int j = this.b.getY();
+ int k = this.b.getZ();
+
+ if (i < blockposition1.getX()) {
+ ++i;
+ } else if (j < blockposition1.getY()) {
+ i = blockposition.getX();
+ ++j;
+ } else if (k < blockposition1.getZ()) {
+ i = blockposition.getX();
+ j = blockposition.getY();
+ ++k;
+ }
+
+ this.b = new BlockPosition(i, j, k);
+ return this.b;
+ }
+ }
+
+ protected Object computeNext() {
+ return this.a();
+ }
+ };
+ }
+ };
+ }
+
+ public static Iterable<BlockPosition.MutableBlockPosition> b(BlockPosition blockposition, BlockPosition blockposition1) {
+ final BlockPosition blockposition2 = new BlockPosition(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()));
+ final BlockPosition blockposition3 = new BlockPosition(Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ()));
+
+ return new Iterable() {
+ public Iterator<BlockPosition.MutableBlockPosition> iterator() {
+ return new AbstractIterator() {
+ private BlockPosition.MutableBlockPosition b = null;
+
+ protected BlockPosition.MutableBlockPosition a() {
+ if (this.b == null) {
+ this.b = new BlockPosition.MutableBlockPosition(blockposition.getX(), blockposition.getY(), blockposition.getZ());
+ return this.b;
+ } else if (this.b.equals(blockposition1)) {
+ return (BlockPosition.MutableBlockPosition) this.endOfData();
+ } else {
+ int i = this.b.getX();
+ int j = this.b.getY();
+ int k = this.b.getZ();
+
+ if (i < blockposition1.getX()) {
+ ++i;
+ } else if (j < blockposition1.getY()) {
+ i = blockposition.getX();
+ ++j;
+ } else if (k < blockposition1.getZ()) {
+ i = blockposition.getX();
+ j = blockposition.getY();
+ ++k;
+ }
+
+ this.b.c = i;
+ this.b.d = j;
+ this.b.e = k;
+ return this.b;
+ }
+ }
+
+ protected Object computeNext() {
+ return this.a();
+ }
+ };
+ }
+ };
+ }
+
+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
+ return this.c(baseblockposition);
+ }
+
+ public static final class MutableBlockPosition extends BlockPosition {
+
+ private int c;
+ private int d;
+ private int e;
+
+ public MutableBlockPosition() {
+ this(0, 0, 0);
+ }
+
+ public MutableBlockPosition(int i, int j, int k) {
+ super(0, 0, 0);
+ this.c = i;
+ this.d = j;
+ this.e = k;
+ }
+
+ public int getX() {
+ return this.c;
+ }
+
+ public int getY() {
+ return this.d;
+ }
+
+ public int getZ() {
+ return this.e;
+ }
+
+ public BlockPosition.MutableBlockPosition c(int i, int j, int k) {
+ this.c = i;
+ this.d = j;
+ this.e = k;
+ return this;
+ }
+
+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
+ return super.c(baseblockposition);
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderFlat.java b/src/main/java/net/minecraft/server/ChunkProviderFlat.java
new file mode 100644
index 0000000..d1e10c6
@ -2966,5 +3323,5 @@ index 0000000..f75e2de
+ }
+}
--
2.7.0.windows.1
2.7.0

View file

@ -0,0 +1,156 @@
From 2834f7d0e06dcee31ff8b6a2ba13be95a913adb2 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Fri, 29 Jan 2016 03:24:21 -0600
Subject: [PATCH] Speedup BlockPos by fixing inlining
Normally the JVM can inline virtual getters by having two sets of code, one is the 'optimized' code and the other is the 'deoptimized' code.
If a single type is used 99% of the time, then its worth it to inline, and to revert to 'deoptimized' the 1% of the time we encounter other types.
But if two types are encountered commonly, then the JVM can't inline them both, and the call overhead remains.
This scenario also occurs with BlockPos and MutableBlockPos.
The variables in BlockPos are final, so MutableBlockPos can't modify them.
MutableBlockPos fixes this by adding custom mutable variables, and overriding the getters to access them.
This approach with utility methods that operate on MutableBlockPos and BlockPos.
Specific examples are BlockPosition.up(), and World.isValidLocation().
It makes these simple methods much slower than they need to be.
This should result in an across the board speedup in anything that accesses blocks or does logic with positions.
This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my mircorbenchmarks.
They had 'callq' (invoke) instead of 'mov' (get from memory) instructions.
diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
index 0b2277c..a685e08 100644
--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java
+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
@@ -5,9 +5,11 @@ import com.google.common.base.Objects;
public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
public static final BaseBlockPosition ZERO = new BaseBlockPosition(0, 0, 0);
- private final int a;
- private final int c;
- private final int d;
+ // PaperSpigot start - Make mutable and protected for MutableBlockPos
+ protected int a;
+ protected int c;
+ protected int d;
+ // PaperSpigot end
public BaseBlockPosition(int i, int j, int k) {
this.a = i;
@@ -39,17 +41,19 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY();
}
- public int getX() {
+ // PaperSpigot start - Only allow one implementation of these methods (make final)
+ public final int getX() {
return this.a;
}
- public int getY() {
+ public final int getY() {
return this.c;
}
- public int getZ() {
+ public final int getZ() {
return this.d;
}
+ // PaperSpigot end
public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX());
@@ -79,7 +83,8 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
}
- public int compareTo(Object object) {
+ // Paperspigot - Signature change, Object -> BaseBlockPosition
+ public int compareTo(BaseBlockPosition object) {
return this.g((BaseBlockPosition) object);
}
}
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
index 2bd5499..8ea95f2 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
@@ -198,9 +198,11 @@ public class BlockPosition extends BaseBlockPosition {
++k;
}
- this.b.c = i;
- this.b.d = j;
- this.b.e = k;
+ // PaperSpigot start
+ this.b.setX(i);
+ this.b.setY(j);
+ this.b.setZ(k);
+ // PaperSpigot stop
return this.b;
}
}
@@ -219,9 +221,25 @@ public class BlockPosition extends BaseBlockPosition {
public static final class MutableBlockPosition extends BlockPosition {
+ // PaperSpigot start - remove our overriding variables
+ /*
private int c;
private int d;
private int e;
+ */
+
+ public void setX(int x) {
+ ((BaseBlockPosition) this).a = x;
+ }
+
+ public void setY(int y) {
+ ((BaseBlockPosition) this).c = y;
+ }
+
+ public void setZ(int z) {
+ ((BaseBlockPosition) this).d = z;
+ }
+ // PaperSpigot end
public MutableBlockPosition() {
this(0, 0, 0);
@@ -229,11 +247,13 @@ public class BlockPosition extends BaseBlockPosition {
public MutableBlockPosition(int i, int j, int k) {
super(0, 0, 0);
- this.c = i;
- this.d = j;
- this.e = k;
+ // PaperSpigot start - modify base x,y,z
+ this.setX(i);
+ this.setY(j);
+ this.setY(k);
}
+ /*
public int getX() {
return this.c;
}
@@ -245,11 +265,13 @@ public class BlockPosition extends BaseBlockPosition {
public int getZ() {
return this.e;
}
+ */
public BlockPosition.MutableBlockPosition c(int i, int j, int k) {
- this.c = i;
- this.d = j;
- this.e = k;
+ setX(i);
+ setY(j);
+ setZ(k);
+ // PaperSpigot end
return this;
}
--
2.7.0