| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 | <?php/* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */namespace Symfony\Component\Stopwatch;/** * Represents an Event managed by Stopwatch. * * @author Fabien Potencier <fabien@symfony.com> */class StopwatchEvent{    /**     * @var StopwatchPeriod[]     */    private $periods = [];    /**     * @var float     */    private $origin;    /**     * @var string     */    private $category;    /**     * @var bool     */    private $morePrecision;    /**     * @var float[]     */    private $started = [];    /**     * @var string     */    private $name;    /**     * @param float       $origin        The origin time in milliseconds     * @param string|null $category      The event category or null to use the default     * @param bool        $morePrecision If true, time is stored as float to keep the original microsecond precision     * @param string|null $name          The event name or null to define the name as default     *     * @throws \InvalidArgumentException When the raw time is not valid     */    public function __construct(float $origin, string $category = null, bool $morePrecision = false, string $name = null)    {        $this->origin = $this->formatTime($origin);        $this->category = \is_string($category) ? $category : 'default';        $this->morePrecision = $morePrecision;        $this->name = $name ?? 'default';    }    /**     * Gets the category.     *     * @return string     */    public function getCategory()    {        return $this->category;    }    /**     * Gets the origin in milliseconds.     *     * @return float     */    public function getOrigin()    {        return $this->origin;    }    /**     * Starts a new event period.     *     * @return $this     */    public function start()    {        $this->started[] = $this->getNow();        return $this;    }    /**     * Stops the last started event period.     *     * @return $this     *     * @throws \LogicException When stop() is called without a matching call to start()     */    public function stop()    {        if (!\count($this->started)) {            throw new \LogicException('stop() called but start() has not been called before.');        }        $this->periods[] = new StopwatchPeriod(array_pop($this->started), $this->getNow(), $this->morePrecision);        return $this;    }    /**     * Checks if the event was started.     *     * @return bool     */    public function isStarted()    {        return !empty($this->started);    }    /**     * Stops the current period and then starts a new one.     *     * @return $this     */    public function lap()    {        return $this->stop()->start();    }    /**     * Stops all non already stopped periods.     */    public function ensureStopped()    {        while (\count($this->started)) {            $this->stop();        }    }    /**     * Gets all event periods.     *     * @return StopwatchPeriod[]     */    public function getPeriods()    {        return $this->periods;    }    /**     * Gets the relative time of the start of the first period in milliseconds.     *     * @return int|float     */    public function getStartTime()    {        if (isset($this->periods[0])) {            return $this->periods[0]->getStartTime();        }        if ($this->started) {            return $this->started[0];        }        return 0;    }    /**     * Gets the relative time of the end of the last period in milliseconds.     *     * @return int|float     */    public function getEndTime()    {        $count = \count($this->periods);        return $count ? $this->periods[$count - 1]->getEndTime() : 0;    }    /**     * Gets the duration of the events in milliseconds (including all periods).     *     * @return int|float     */    public function getDuration()    {        $periods = $this->periods;        $left = \count($this->started);        for ($i = $left - 1; $i >= 0; --$i) {            $periods[] = new StopwatchPeriod($this->started[$i], $this->getNow(), $this->morePrecision);        }        $total = 0;        foreach ($periods as $period) {            $total += $period->getDuration();        }        return $total;    }    /**     * Gets the max memory usage of all periods in bytes.     *     * @return int     */    public function getMemory()    {        $memory = 0;        foreach ($this->periods as $period) {            if ($period->getMemory() > $memory) {                $memory = $period->getMemory();            }        }        return $memory;    }    /**     * Return the current time relative to origin in milliseconds.     *     * @return float     */    protected function getNow()    {        return $this->formatTime(microtime(true) * 1000 - $this->origin);    }    /**     * Formats a time.     *     * @throws \InvalidArgumentException When the raw time is not valid     */    private function formatTime(float $time): float    {        return round($time, 1);    }    /**     * Gets the event name.     */    public function getName(): string    {        return $this->name;    }    public function __toString(): string    {        return sprintf('%s/%s: %.2F MiB - %d ms', $this->getCategory(), $this->getName(), $this->getMemory() / 1024 / 1024, $this->getDuration());    }}
 |