Add specialized entityBaseTick timer for item entities

since item merging is a potential hotspot, we want to know if this code section is a performance problem.
Current timers only tell us whether overall ticking of a particular entity is slow, but that includes movement and therefore isn't particularly helpful.
This commit is contained in:
Dylan K. Taylor 2023-03-19 15:59:06 +00:00
parent 7bc5d8c824
commit 054c06fab9
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 48 additions and 38 deletions

View File

@ -41,6 +41,7 @@ use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\timings\Timings;
use function max; use function max;
class ItemEntity extends Entity{ class ItemEntity extends Entity{
@ -113,57 +114,63 @@ class ItemEntity extends Entity{
return false; return false;
} }
$hasUpdate = parent::entityBaseTick($tickDiff); Timings::$itemEntityBaseTick->startTiming();
try{
if($this->isFlaggedForDespawn()){ $hasUpdate = parent::entityBaseTick($tickDiff);
return $hasUpdate;
}
if($this->pickupDelay !== self::NEVER_DESPAWN && $this->pickupDelay > 0){ //Infinite delay if($this->isFlaggedForDespawn()){
$hasUpdate = true; return $hasUpdate;
$this->pickupDelay -= $tickDiff;
if($this->pickupDelay < 0){
$this->pickupDelay = 0;
} }
}
if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){ if($this->pickupDelay !== self::NEVER_DESPAWN && $this->pickupDelay > 0){ //Infinite delay
$mergeable = [$this]; //in case the merge target ends up not being this $hasUpdate = true;
$mergeTarget = $this; $this->pickupDelay -= $tickDiff;
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){ if($this->pickupDelay < 0){
if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){ $this->pickupDelay = 0;
continue;
} }
}
if($entity->isMergeable($this)){ if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
$mergeable[] = $entity; $mergeable = [$this]; //in case the merge target ends up not being this
if($entity->item->getCount() > $mergeTarget->item->getCount()){ $mergeTarget = $this;
$mergeTarget = $entity; foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){
continue;
}
if($entity->isMergeable($this)){
$mergeable[] = $entity;
if($entity->item->getCount() > $mergeTarget->item->getCount()){
$mergeTarget = $entity;
}
}
}
foreach($mergeable as $itemEntity){
if($itemEntity !== $mergeTarget){
$itemEntity->tryMergeInto($mergeTarget);
} }
} }
} }
foreach($mergeable as $itemEntity){
if($itemEntity !== $mergeTarget){ if(!$this->isFlaggedForDespawn() && $this->despawnDelay !== self::NEVER_DESPAWN){
$itemEntity->tryMergeInto($mergeTarget); $hasUpdate = true;
$this->despawnDelay -= $tickDiff;
if($this->despawnDelay <= 0){
$ev = new ItemDespawnEvent($this);
$ev->call();
if($ev->isCancelled()){
$this->despawnDelay = self::DEFAULT_DESPAWN_DELAY;
}else{
$this->flagForDespawn();
}
} }
} }
}
if(!$this->isFlaggedForDespawn() && $this->despawnDelay !== self::NEVER_DESPAWN){ return $hasUpdate;
$hasUpdate = true; }finally{
$this->despawnDelay -= $tickDiff; Timings::$itemEntityBaseTick->stopTiming();
if($this->despawnDelay <= 0){
$ev = new ItemDespawnEvent($this);
$ev->call();
if($ev->isCancelled()){
$this->despawnDelay = self::DEFAULT_DESPAWN_DELAY;
}else{
$this->flagForDespawn();
}
}
} }
return $hasUpdate;
} }
/** /**

View File

@ -107,6 +107,8 @@ abstract class Timings{
/** @var TimingsHandler */ /** @var TimingsHandler */
public static $livingEntityBaseTick; public static $livingEntityBaseTick;
public static TimingsHandler $itemEntityBaseTick;
/** @var TimingsHandler */ /** @var TimingsHandler */
public static $schedulerSync; public static $schedulerSync;
/** @var TimingsHandler */ /** @var TimingsHandler */
@ -200,6 +202,7 @@ abstract class Timings{
self::$entityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Entity Base Tick"); self::$entityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Entity Base Tick");
self::$livingEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Entity Base Tick - Living"); self::$livingEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Entity Base Tick - Living");
self::$itemEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Entity Base Tick - ItemEntity");
self::$schedulerSync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Sync Tasks"); self::$schedulerSync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Sync Tasks");
self::$schedulerAsync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Async Tasks"); self::$schedulerAsync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Async Tasks");