Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
Timer
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
7 / 7
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 test
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 addMark
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 setMark
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getMark
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMarks
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 diff
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework Debug Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\Debug;
11
12use JetBrains\PhpStorm\ArrayShape;
13
14/**
15 * Class Timer.
16 *
17 * @package debug
18 */
19class Timer
20{
21    /**
22     * @var array<string,array<string,mixed>>
23     */
24    protected array $marks = [];
25    protected int $testsCount = 1;
26
27    /**
28     * Timer constructor.
29     */
30    public function __construct()
31    {
32        $this->addMark('debug[start]');
33    }
34
35    /**
36     * @param int $times
37     * @param callable $function
38     * @param bool $flush
39     *
40     * @return array<string,string> Two keys - "memory" in MB and "time" in seconds
41     */
42    #[ArrayShape(['memory' => 'string', 'time' => 'string'])]
43    public function test(int $times, callable $function, bool $flush = false) : array
44    {
45        if ( ! $flush) {
46            \ob_start();
47        }
48        $this->testsCount++;
49        $this->addMark('test[' . $this->testsCount . '][start]');
50        for ($i = 0; $i < $times; $i++) {
51            $function();
52        }
53        $this->addMark('test[' . ($this->testsCount) . '][end]');
54        if ( ! $flush) {
55            \ob_end_clean();
56        }
57        return $this->diff(
58            'test[' . $this->testsCount . '][start]',
59            'test[' . $this->testsCount . '][end]'
60        );
61    }
62
63    /**
64     * @param string $name
65     *
66     * @return static
67     */
68    public function addMark(string $name) : static
69    {
70        $this->marks[$name] = [
71            'memory' => \memory_get_usage(),
72            'time' => \microtime(true),
73        ];
74        return $this;
75    }
76
77    /**
78     * @param string $name
79     * @param int $memoryUsage
80     * @param float $microtime
81     *
82     * @return static
83     */
84    public function setMark(string $name, int $memoryUsage, float $microtime) : static
85    {
86        $this->marks[$name] = [
87            'memory' => $memoryUsage,
88            'time' => $microtime,
89        ];
90        return $this;
91    }
92
93    /**
94     * @param string $name
95     *
96     * @return array<string,string>|false
97     */
98    public function getMark(string $name) : array | false
99    {
100        return $this->marks[$name] ?? false;
101    }
102
103    /**
104     * @param bool $format
105     *
106     * @return array<string,array<string,mixed>>
107     */
108    public function getMarks(bool $format = false) : array
109    {
110        $marks = $this->marks;
111        if ($format) {
112            foreach ($marks as &$mark) {
113                $mark['memory'] = \number_format($mark['memory'] / 1024 / 1024, 3) . ' MB';
114                $mark['time'] = \number_format($mark['time'], 3) . ' s';
115            }
116        }
117        return $marks;
118    }
119
120    /**
121     * @param string $from
122     * @param string $to
123     *
124     * @return array<string,string> Two keys: memory in MB and time in seconds
125     */
126    #[ArrayShape(['memory' => 'string', 'time' => 'string'])]
127    public function diff(string $from, string $to) : array
128    {
129        $number = $this->marks[$to]['memory'] - $this->marks[$from]['memory'];
130        $number = \number_format($number / 1024 / 1024, 3);
131        $diff = [];
132        $diff['memory'] = $number . ' MB';
133        $number = $this->marks[$to]['time'] - $this->marks[$from]['time'];
134        $number = \number_format($number, 3);
135        $diff['time'] = $number . ' s';
136        return $diff;
137    }
138}