From ee7d4728d8c813af39cab5b03736cc6df76f2a2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Dec 2022 21:20:21 +0000 Subject: [PATCH] World: added cache for isChunkTickable() this considerably reduces the amount of work done by the function, since it's usually checking the same chunks over and over again. --- src/world/World.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index b20960755..8c14c7fc1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1151,6 +1151,8 @@ class World implements ChunkManager{ /** @var bool[] $chunkTickList chunkhash => dummy */ $chunkTickList = []; + $chunkTickableCache = []; + $centerChunks = []; $selector = new ChunkSelector(); @@ -1170,7 +1172,7 @@ class World implements ChunkManager{ $centerChunkZ ) as $hash){ World::getXZ($hash, $chunkX, $chunkZ); - if(!isset($chunkTickList[$hash]) && isset($this->chunks[$hash]) && $this->isChunkTickable($chunkX, $chunkZ)){ + if(!isset($chunkTickList[$hash]) && isset($this->chunks[$hash]) && $this->isChunkTickable($chunkX, $chunkZ, $chunkTickableCache)){ $chunkTickList[$hash] = true; } } @@ -1185,14 +1187,29 @@ class World implements ChunkManager{ } } - private function isChunkTickable(int $chunkX, int $chunkZ) : bool{ + /** + * @param bool[] &$cache + * + * @phpstan-param array $cache + * @phpstan-param-out array $cache + */ + private function isChunkTickable(int $chunkX, int $chunkZ, array &$cache) : bool{ for($cx = -1; $cx <= 1; ++$cx){ for($cz = -1; $cz <= 1; ++$cz){ + $chunkHash = World::chunkHash($chunkX + $cx, $chunkZ + $cz); + if(isset($cache[$chunkHash])){ + if(!$cache[$chunkHash]){ + return false; + } + continue; + } if($this->isChunkLocked($chunkX + $cx, $chunkZ + $cz)){ + $cache[$chunkHash] = false; return false; } $adjacentChunk = $this->getChunk($chunkX + $cx, $chunkZ + $cz); if($adjacentChunk === null || !$adjacentChunk->isPopulated()){ + $cache[$chunkHash] = false; return false; } $lightPopulatedState = $adjacentChunk->isLightPopulated(); @@ -1200,8 +1217,11 @@ class World implements ChunkManager{ if($lightPopulatedState === false){ $this->orderLightPopulation($chunkX + $cx, $chunkZ + $cz); } + $cache[$chunkHash] = false; return false; } + + $cache[$chunkHash] = true; } }