Passed
Push — master ( 667c74...5caefd )
by Alexander
04:36
created

Benchmark::getTimers()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 15
rs 10
1
<?php
2
3
/**
4
 * Lenevor Framework
5
 *
6
 * LICENSE
7
 *
8
 * This source file is subject to the new BSD license that is bundled
9
 * with this package in the file license.md.
10
 * It is also available through the world-wide-web at this URL:
11
 * https://lenevor.com/license
12
 * If you did not receive a copy of the license and are unable to
13
 * obtain it through the world-wide-web, please send an email
14
 * to [email protected] so we can send you a copy immediately.
15
 *
16
 * @package     Lenevor
17
 * @subpackage  Base
18
 * @link        https://lenevor.com
19
 * @copyright   Copyright (c) 2019 - 2023 Alexander Campo <[email protected]>
20
 * @license     https://opensource.org/licenses/BSD-3-Clause New BSD license or see https://lenevor.com/license or see /license.md
21
 */
22
23
namespace Syscodes\Components\Stopwatch;
24
25
use Syscodes\Components\Stopwatch\Exceptions\BenchmarckException;
26
27
/**
28
 * Provides a simple way to measure the amount of time
29
 * that elapses between two points.
30
 */
31
class Benchmark 
32
{
33
    /**
34
     * List all the timers.
35
     * 
36
     * @var array $timers
37
     */
38
    protected $timers = [];
39
40
    /**
41
     * Starts a timer running.
42
     * 
43
     * @param  string  $name
44
     * @param  float|null  $time
45
     * 
46
     * @return static
47
     */
48
    public function start(string $name, float $time = null): static
49
    {
50
        $this->timers[strtolower($name)] = [
51
            'start' => ! empty($time) ? $time : microtime(true),
52
            'end'   => null
53
        ];
54
55
        return $this;
56
    }
57
58
    /**
59
     * Stop a running timer.
60
     * 
61
     * @param  string  $name
62
     * 
63
     * @return static
64
     */
65
    public function stop(string $name): static
66
    {
67
        $name = strtolower($name);
68
69
        if (empty($this->timers[$name])) {
70
            throw new BenchmarckException('Cannot stop timer: invalid name given');
71
        }
72
73
        $this->timers[$name]['end'] = microtime(true);
74
75
        return $this;
76
    }
77
78
    /**
79
     * Returns the duration of a recorded timer.
80
     * 
81
     * @param  string  $name
82
     * @param  int  $decimals
83
     * 
84
     * @return null|float
85
     */
86
    public function getElapsedTime(string $name, int $decimals = 4)
87
    {
88
        $name = strtolower($name);
89
90
        if (empty($this->timers[$name])) {
91
            return null;
92
        }
93
94
        $timer = $this->timers[$name];
95
96
        if (empty($timer['end'])) {
97
            $timer['end'] = microtime(true);
98
        }
99
100
        $operation = $timer['end'] - $timer['start'];
101
102
        return (float) number_format($operation, $decimals).$this->formatPeriod($operation);
0 ignored issues
show
Bug Best Practice introduced by
The expression return (double)number_fo...ormatPeriod($operation) returns the type string which is incompatible with the documented return type double|null.
Loading history...
103
    }
104
105
    /**
106
     * Returns the array of timers, with the duration pre-calculated for you.
107
     * 
108
     * @param  int  $decimals
109
     * 
110
     * @return array
111
     */
112
    public function getTimers(int $decimals = 4): array
113
    {
114
        $timers = $this->timers;
115
116
        foreach ($timers as $timer) {
117
            if (empty($timer['end'])) {
118
                $timer['end'] = microtime(true);
119
            }
120
121
            $operation = $timer['end'] - $timer['start'];
122
123
            $timer['duration'] = (float) number_format($operation, $decimals).$this->formatPeriod($operation);
124
        }
125
126
        return $timers;
127
    }
128
129
    /**
130
     * Returns the converter in words of the loading time.
131
     * 
132
     * @param  float  $operation
133
     * 
134
     * @return string
135
     */
136
    protected function formatPeriod(float $operation): string
137
    { 
138
        $duration = $operation; 
139
        $hours    = (int) ($duration / 60 / 60); 
140
        $minutes  = (int) (($duration / 60) - $hours * 60); 
141
        $seconds  = (int) ($duration - $hours * 60 * 60 - $minutes * 60); 
142
        
143
        if ($seconds <= 0) {
144
           return ' ms';
145
        } elseif ($seconds > 0) {
146
            return ' s';
147
        }
148
149
        return ' m';
150
    } 
151
152
    /**
153
     * Checks whether or not a timer with the specified name exists.
154
     * 
155
     * @param  string  $name
156
     * 
157
     * @return bool
158
     */
159
    public function has(string $name): bool
160
    {
161
        return array_key_exists(strtolower($name), $this->timers);
162
    }
163
}