Profiler   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 4
dl 0
loc 223
ccs 66
cts 66
cp 1
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A start() 0 11 1
A stop() 0 15 3
A addBenchmark() 0 6 1
A getDuration() 0 7 2
A getStartTime() 0 4 1
A getBenchmarks() 0 4 1
A getLastBenchmark() 0 9 2
A addAggregator() 0 4 1
A getAggregators() 0 4 1
A aggregate() 0 6 2
A count() 0 4 1
A current() 0 4 1
A next() 0 4 1
A key() 0 4 1
A valid() 0 10 3
A rewind() 0 4 1
1
<?php
2
/**
3
 * @author @fabfuel <[email protected]>
4
 * @created 13.11.14, 07:47
5
 */
6
namespace Fabfuel\Prophiler;
7
8
use Fabfuel\Prophiler\Benchmark\BenchmarkFactory;
9
use Fabfuel\Prophiler\Benchmark\BenchmarkInterface;
10
use Fabfuel\Prophiler\Exception\UnknownBenchmarkException;
11
12
class Profiler implements ProfilerInterface
13
{
14
    /**
15
     * @var BenchmarkInterface[]
16
     */
17
    protected $benchmarks = [];
18
19
    /**
20
     * @var AggregatorInterface[]
21
     */
22
    protected $aggregators = [];
23
24
    /**
25
     * @var double Starting time
26
     */
27
    protected $start;
28
29
    /**
30
     * Save start time on construction
31
     */
32 4
    public function __construct()
33
    {
34 4
        $this->start = (double)microtime(true);
35 4
    }
36
37
    /**
38
     * Start a new benchmark
39
     *
40
     * @param string $name Unique identifier like e.g. Class::Method (\Foobar\MyClass::doSomething)
41
     * @param array $metadata Additional metadata
42
     * @param string $component Name of the component which triggered the benchmark, e.g. "App", "Database"
43
     * @return BenchmarkInterface The started benchmark
44
     */
45 1
    public function start($name, array $metadata = [], $component = null)
46
    {
47 1
        $benchmark = BenchmarkFactory::getBenchmark(
48 1
            $name,
49 1
            $metadata,
50
            $component
51 1
        );
52 1
        $benchmark->start();
53 1
        $this->addBenchmark($benchmark);
54 1
        return $benchmark;
55
    }
56
57
    /**
58
     * Stop a running benchmark
59
     * If no benchmark provided, the last started benchmark is stopped
60
     *
61
     * @param BenchmarkInterface $benchmark Benchmark identifier
62
     * @param array $metadata Additional metadata
63
     * @throws UnknownBenchmarkException
64
     * @return BenchmarkInterface $benchmark
65
     */
66 4
    public function stop(BenchmarkInterface $benchmark = null, array $metadata = [])
67
    {
68 4
        if (is_null($benchmark)) {
69 2
            $benchmark = $this->getLastBenchmark();
70 1
        }
71 3
        if (!isset($this->benchmarks[spl_object_hash($benchmark)])) {
72 1
            throw new UnknownBenchmarkException('Benchmark not present in profiler');
73
        }
74 2
        $benchmark->stop();
75 2
        $benchmark->addMetadata($metadata);
76
77 2
        $this->aggregate($benchmark);
78
79 2
        return $benchmark;
80
    }
81
82
    /**
83
     * @param BenchmarkInterface $benchmark
84
     * @return $this
85
     */
86 1
    public function addBenchmark(BenchmarkInterface $benchmark)
87
    {
88 1
        $identifier = spl_object_hash($benchmark);
89 1
        $this->benchmarks[$identifier] = $benchmark;
90 1
        return $this;
91
    }
92
93
    /**
94
     * Get the total number of elapsed time in milliseconds
95
     *
96
     * @return double Total number of elapsed milliseconds
97
     */
98 2
    public function getDuration()
99
    {
100 2
        if ($this->count()) {
101 1
            return ($this->getLastBenchmark()->getEndTime() - $this->getStartTime()) * 1000;
102
        }
103 1
        return (microtime(true) - $this->getStartTime()) * 1000;
104
    }
105
106
    /**
107
     * Get the start of the profiler in microtime
108
     *
109
     * @return double Timestamp in microtime
110
     */
111 1
    public function getStartTime()
112
    {
113 1
        return $this->start;
114
    }
115
116
    /**
117
     * Return all measured benchmarks
118
     *
119
     * @return BenchmarkInterface[]
120
     */
121 1
    public function getBenchmarks()
122
    {
123 1
        return $this->benchmarks;
124
    }
125
126
    /**
127
     * @return BenchmarkInterface
128
     * @throws UnknownBenchmarkException
129
     */
130 3
    public function getLastBenchmark()
131
    {
132 3
        $lastBenchmarkSlice = array_slice($this->benchmarks, -1, 1, true);
133 3
        $lastBenchmark = current($lastBenchmarkSlice);
134 3
        if ($lastBenchmark) {
135 1
            return $lastBenchmark;
136
        }
137 2
        throw new UnknownBenchmarkException('No benchmarks to return last one');
138
    }
139
140
    /**
141
     * Add an aggregator to the profiler
142
     *
143
     * @param AggregatorInterface $aggregator
144
     * @return $this
145
     */
146 2
    public function addAggregator(AggregatorInterface $aggregator)
147
    {
148 2
        $this->aggregators[] = $aggregator;
149 2
    }
150
151
    /**
152
     * @return AggregatorInterface[]
153
     */
154 2
    public function getAggregators()
155
    {
156 2
        return $this->aggregators;
157
    }
158
159
    /**
160
     * @param BenchmarkInterface $benchmark
161
     */
162 1
    public function aggregate(BenchmarkInterface $benchmark)
163
    {
164 1
        foreach ($this->getAggregators() as $aggregator) {
165 1
            $aggregator->aggregate($benchmark);
166 1
        }
167 1
    }
168
169
    /**
170
     * Get the total number of benchmarks
171
     *
172
     * @return int Total number of benchmarks
173
     */
174 1
    public function count()
175
    {
176 1
        return count($this->benchmarks);
177
    }
178
179
    /**
180
     * Return the current benchmark
181
     *
182
     * @return BenchmarkInterface|bool
183
     */
184 1
    public function current()
185
    {
186 1
        return current($this->benchmarks);
187
    }
188
189
    /**
190
     * Move forward to next benchmark
191
     *
192
     * @return void
193
     */
194 1
    public function next()
195
    {
196 1
        next($this->benchmarks);
197 1
    }
198
199
    /**
200
     * Return the key of the current Benchmark
201
     *
202
     * @return string
203
     */
204 1
    public function key()
205
    {
206 1
        return key($this->benchmarks);
207
    }
208
209
    /**
210
     * Checks if current position is valid
211
     *
212
     * @return bool
213
     */
214 1
    public function valid()
215
    {
216 1
        $key = key($this->benchmarks);
217
218 1
        if ($key === false || $key === null) {
219 1
            return false;
220
        }
221
222 1
        return array_key_exists($key, $this->benchmarks);
223
    }
224
225
    /**
226
     * Rewind the Iterator to the first benchmark
227
     *
228
     * @return void
229
     */
230 1
    public function rewind()
231
    {
232 1
        reset($this->benchmarks);
233 1
    }
234
}
235