From 78aa757549a0f779d240981b2437ebe66abc52a3 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 26 Apr 2022 18:53:25 +0100 Subject: [PATCH] Memorize getRenderBoundingBox This takes a non-trivial amount of time on the render thread[^1], so worth doing. I don't actually think the allocation is the heavy thing here - VisualVM says it's toWorldPos being slow. I'm not sure why - possibly just all the block property lookups? [^2] [^1]: To be clear, this is with 120 monitors and no other block entities with custom renderers. so not really representative. [^2]: I wish I could provide a narrower range, but it varies so much between me restarting the game. Makes it impossible to benchmark anything! --- .../peripheral/monitor/TileMonitor.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java index 7a907fb04..cbe88a763 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/TileMonitor.java @@ -70,6 +70,11 @@ public class TileMonitor extends TileGeneric private int xIndex = 0; private int yIndex = 0; + private BlockPos bbPos; + private BlockState bbState; + private int bbX, bbY, bbWidth, bbHeight; + private AxisAlignedBB boundingBox; + public TileMonitor( TileEntityType type, boolean advanced ) { super( type ); @@ -624,9 +629,25 @@ public class TileMonitor extends TileGeneric @Override public AxisAlignedBB getRenderBoundingBox() { + // We attempt to cache the bounding box to save having to do property lookups (and allocations!) on every frame. + // Unfortunately the AABB does depend on quite a lot of state, so we need to add a bunch of extra fields - + // ideally these'd be a single object, but I don't think worth doing until Java has value types. + if( boundingBox != null && getBlockState().equals( bbState ) && getBlockPos().equals( bbPos ) && + xIndex == bbX && yIndex == bbY && width == bbWidth && height == bbHeight ) + { + return boundingBox; + } + + bbState = getBlockState(); + bbPos = getBlockPos(); + bbX = xIndex; + bbY = yIndex; + bbWidth = width; + bbHeight = height; + BlockPos startPos = toWorldPos( 0, 0 ); BlockPos endPos = toWorldPos( width, height ); - return new AxisAlignedBB( + return boundingBox = new AxisAlignedBB( Math.min( startPos.getX(), endPos.getX() ), Math.min( startPos.getY(), endPos.getY() ), Math.min( startPos.getZ(), endPos.getZ() ),