mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-12 12:55:21 +00:00
This is better for performance because these then don't need to be reevaluated every time they are called. When encountering an unqualified function or constant reference, PHP will first try to locate a symbol in the current namespace by that name, and then fall back to the global namespace. This short-circuits the check, which has substantial performance effects in some cases - in particular, ord(), chr() and strlen() show ~1500x faster calls when they are fully qualified. However, this doesn't mean that PM is getting a massive amount faster. In real world terms, this translates to about 10-15% performance improvement. But before anyone gets excited, you should know that the CodeOptimizer in the PreProcessor repo has been applying fully-qualified symbol optimizations to Jenkins builds for years, which is one of the reasons why Jenkins builds have better performance than home-built or source installations. We're choosing to do this for the sake of future SafePHP integration and also to be able to get rid of the buggy CodeOptimizer, so that phar and source are more consistent.
228 lines
7.8 KiB
PHP
228 lines
7.8 KiB
PHP
<?php
|
|
|
|
/*
|
|
*
|
|
* ____ _ _ __ __ _ __ __ ____
|
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* @author PocketMine Team
|
|
* @link http://www.pocketmine.net/
|
|
*
|
|
*
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace pocketmine\timings;
|
|
|
|
use pocketmine\entity\Entity;
|
|
use pocketmine\network\mcpe\protocol\DataPacket;
|
|
use pocketmine\Player;
|
|
use pocketmine\scheduler\TaskHandler;
|
|
use pocketmine\tile\Tile;
|
|
use function dechex;
|
|
|
|
abstract class Timings{
|
|
|
|
/** @var TimingsHandler */
|
|
public static $fullTickTimer;
|
|
/** @var TimingsHandler */
|
|
public static $serverTickTimer;
|
|
/** @var TimingsHandler */
|
|
public static $memoryManagerTimer;
|
|
/** @var TimingsHandler */
|
|
public static $garbageCollectorTimer;
|
|
/** @var TimingsHandler */
|
|
public static $titleTickTimer;
|
|
/** @var TimingsHandler */
|
|
public static $playerNetworkTimer;
|
|
/** @var TimingsHandler */
|
|
public static $playerNetworkReceiveTimer;
|
|
/** @var TimingsHandler */
|
|
public static $playerChunkOrderTimer;
|
|
/** @var TimingsHandler */
|
|
public static $playerChunkSendTimer;
|
|
/** @var TimingsHandler */
|
|
public static $connectionTimer;
|
|
/** @var TimingsHandler */
|
|
public static $schedulerTimer;
|
|
/** @var TimingsHandler */
|
|
public static $serverCommandTimer;
|
|
/** @var TimingsHandler */
|
|
public static $worldSaveTimer;
|
|
/** @var TimingsHandler */
|
|
public static $populationTimer;
|
|
/** @var TimingsHandler */
|
|
public static $generationCallbackTimer;
|
|
/** @var TimingsHandler */
|
|
public static $permissibleCalculationTimer;
|
|
/** @var TimingsHandler */
|
|
public static $permissionDefaultTimer;
|
|
|
|
/** @var TimingsHandler */
|
|
public static $entityMoveTimer;
|
|
/** @var TimingsHandler */
|
|
public static $playerCheckNearEntitiesTimer;
|
|
/** @var TimingsHandler */
|
|
public static $tickEntityTimer;
|
|
/** @var TimingsHandler */
|
|
public static $tickTileEntityTimer;
|
|
|
|
/** @var TimingsHandler */
|
|
public static $timerEntityBaseTick;
|
|
/** @var TimingsHandler */
|
|
public static $timerLivingEntityBaseTick;
|
|
|
|
/** @var TimingsHandler */
|
|
public static $schedulerSyncTimer;
|
|
/** @var TimingsHandler */
|
|
public static $schedulerAsyncTimer;
|
|
|
|
/** @var TimingsHandler */
|
|
public static $playerCommandTimer;
|
|
|
|
/** @var TimingsHandler */
|
|
public static $craftingDataCacheRebuildTimer;
|
|
|
|
/** @var TimingsHandler[] */
|
|
public static $entityTypeTimingMap = [];
|
|
/** @var TimingsHandler[] */
|
|
public static $tileEntityTypeTimingMap = [];
|
|
/** @var TimingsHandler[] */
|
|
public static $packetReceiveTimingMap = [];
|
|
/** @var TimingsHandler[] */
|
|
public static $packetSendTimingMap = [];
|
|
/** @var TimingsHandler[] */
|
|
public static $pluginTaskTimingMap = [];
|
|
|
|
public static function init(){
|
|
if(self::$serverTickTimer instanceof TimingsHandler){
|
|
return;
|
|
}
|
|
|
|
self::$fullTickTimer = new TimingsHandler("Full Server Tick");
|
|
self::$serverTickTimer = new TimingsHandler("** Full Server Tick", self::$fullTickTimer);
|
|
self::$memoryManagerTimer = new TimingsHandler("Memory Manager");
|
|
self::$garbageCollectorTimer = new TimingsHandler("Garbage Collector", self::$memoryManagerTimer);
|
|
self::$titleTickTimer = new TimingsHandler("Console Title Tick");
|
|
self::$playerNetworkTimer = new TimingsHandler("Player Network Send");
|
|
self::$playerNetworkReceiveTimer = new TimingsHandler("Player Network Receive");
|
|
self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks");
|
|
self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks");
|
|
self::$connectionTimer = new TimingsHandler("Connection Handler");
|
|
self::$schedulerTimer = new TimingsHandler("Scheduler");
|
|
self::$serverCommandTimer = new TimingsHandler("Server Command");
|
|
self::$worldSaveTimer = new TimingsHandler("World Save");
|
|
self::$populationTimer = new TimingsHandler("World Population");
|
|
self::$generationCallbackTimer = new TimingsHandler("World Generation Callback");
|
|
self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation");
|
|
self::$permissionDefaultTimer = new TimingsHandler("Default Permission Calculation");
|
|
|
|
self::$entityMoveTimer = new TimingsHandler("** entityMove");
|
|
self::$playerCheckNearEntitiesTimer = new TimingsHandler("** checkNearEntities");
|
|
self::$tickEntityTimer = new TimingsHandler("** tickEntity");
|
|
self::$tickTileEntityTimer = new TimingsHandler("** tickTileEntity");
|
|
|
|
self::$timerEntityBaseTick = new TimingsHandler("** entityBaseTick");
|
|
self::$timerLivingEntityBaseTick = new TimingsHandler("** livingEntityBaseTick");
|
|
|
|
self::$schedulerSyncTimer = new TimingsHandler("** Scheduler - Sync Tasks");
|
|
self::$schedulerAsyncTimer = new TimingsHandler("** Scheduler - Async Tasks");
|
|
|
|
self::$playerCommandTimer = new TimingsHandler("** playerCommand");
|
|
self::$craftingDataCacheRebuildTimer = new TimingsHandler("** craftingDataCacheRebuild");
|
|
|
|
}
|
|
|
|
/**
|
|
* @param TaskHandler $task
|
|
* @param int $period
|
|
*
|
|
* @return TimingsHandler
|
|
*/
|
|
public static function getScheduledTaskTimings(TaskHandler $task, int $period) : TimingsHandler{
|
|
$name = "Task: " . ($task->getOwnerName() ?? "Unknown") . " Runnable: " . $task->getTaskName();
|
|
|
|
if($period > 0){
|
|
$name .= "(interval:" . $period . ")";
|
|
}else{
|
|
$name .= "(Single)";
|
|
}
|
|
|
|
if(!isset(self::$pluginTaskTimingMap[$name])){
|
|
self::$pluginTaskTimingMap[$name] = new TimingsHandler($name, self::$schedulerSyncTimer);
|
|
}
|
|
|
|
return self::$pluginTaskTimingMap[$name];
|
|
}
|
|
|
|
/**
|
|
* @param Entity $entity
|
|
*
|
|
* @return TimingsHandler
|
|
*/
|
|
public static function getEntityTimings(Entity $entity) : TimingsHandler{
|
|
$entityType = (new \ReflectionClass($entity))->getShortName();
|
|
if(!isset(self::$entityTypeTimingMap[$entityType])){
|
|
if($entity instanceof Player){
|
|
self::$entityTypeTimingMap[$entityType] = new TimingsHandler("** tickEntity - EntityPlayer", self::$tickEntityTimer);
|
|
}else{
|
|
self::$entityTypeTimingMap[$entityType] = new TimingsHandler("** tickEntity - " . $entityType, self::$tickEntityTimer);
|
|
}
|
|
}
|
|
|
|
return self::$entityTypeTimingMap[$entityType];
|
|
}
|
|
|
|
/**
|
|
* @param Tile $tile
|
|
*
|
|
* @return TimingsHandler
|
|
*/
|
|
public static function getTileEntityTimings(Tile $tile) : TimingsHandler{
|
|
$tileType = (new \ReflectionClass($tile))->getShortName();
|
|
if(!isset(self::$tileEntityTypeTimingMap[$tileType])){
|
|
self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler("** tickTileEntity - " . $tileType, self::$tickTileEntityTimer);
|
|
}
|
|
|
|
return self::$tileEntityTypeTimingMap[$tileType];
|
|
}
|
|
|
|
/**
|
|
* @param DataPacket $pk
|
|
*
|
|
* @return TimingsHandler
|
|
*/
|
|
public static function getReceiveDataPacketTimings(DataPacket $pk) : TimingsHandler{
|
|
if(!isset(self::$packetReceiveTimingMap[$pk::NETWORK_ID])){
|
|
$pkName = (new \ReflectionClass($pk))->getShortName();
|
|
self::$packetReceiveTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** receivePacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkReceiveTimer);
|
|
}
|
|
|
|
return self::$packetReceiveTimingMap[$pk::NETWORK_ID];
|
|
}
|
|
|
|
|
|
/**
|
|
* @param DataPacket $pk
|
|
*
|
|
* @return TimingsHandler
|
|
*/
|
|
public static function getSendDataPacketTimings(DataPacket $pk) : TimingsHandler{
|
|
if(!isset(self::$packetSendTimingMap[$pk::NETWORK_ID])){
|
|
$pkName = (new \ReflectionClass($pk))->getShortName();
|
|
self::$packetSendTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkTimer);
|
|
}
|
|
|
|
return self::$packetSendTimingMap[$pk::NETWORK_ID];
|
|
}
|
|
}
|