Completed
Branch BUG-10738-inconsistency-in-ses... (cda363)
by
unknown
13:38 queued 12s
created

Benchmark::displayResults()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\services;
4
5
defined('EVENT_ESPRESSO_VERSION') || exit;
6
7
8
9
/**
10
 * Class Benchmark
11
 * Useful for measuring the performance of a block of code
12
 *
13
 * @package       Event Espresso
14
 * @author        Brent Christensen
15
 * @since         $VID:$
16
 */
17
class Benchmark
18
{
19
20
    /**
21
     * array containing the start time for the timers
22
     */
23
    private static $start_times;
0 ignored issues
show
Unused Code introduced by
The property $start_times is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
24
25
    /**
26
     * array containing all the timer'd times, which can be outputted via show_times()
27
     */
28
    private static $times = array();
0 ignored issues
show
Unused Code introduced by
The property $times is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
29
30
    /**
31
     * @var array
32
     */
33
    protected static $memory_usage = array();
34
35
36
37
    /**
38
     * whether to benchmark code or not
39
     */
40
    public static function doNotRun()
41
    {
42
        return ! WP_DEBUG || (defined('DOING_AJAX') && DOING_AJAX);
43
    }
44
45
46
47
    /**
48
     * resetTimes
49
     */
50
    public static function resetTimes()
51
    {
52
        Benchmark::$times = array();
53
    }
54
55
56
57
    /**
58
     * Add Benchmark::startTimer() before a block of code you want to measure the performance of
59
     *
60
     * @param null $timer_name
61
     */
62
    public static function startTimer($timer_name = null)
63
    {
64
        if (Benchmark::doNotRun()) {
65
            return;
66
        }
67
        $timer_name = $timer_name !== '' ? $timer_name : get_called_class();
68
        Benchmark::$start_times[$timer_name] = microtime(true);
69
    }
70
71
72
73
    /**
74
     * Add Benchmark::stopTimer() after a block of code you want to measure the performance of
75
     *
76
     * @param string $timer_name
77
     */
78
    public static function stopTimer($timer_name = '')
79
    {
80
        if (Benchmark::doNotRun()) {
81
            return;
82
        }
83
        $timer_name = $timer_name !== '' ? $timer_name : get_called_class();
84
        if (isset(Benchmark::$start_times[$timer_name])) {
85
            $start_time = Benchmark::$start_times[$timer_name];
86
            unset(Benchmark::$start_times[$timer_name]);
87
        } else {
88
            $start_time = array_pop(Benchmark::$start_times);
89
        }
90
        Benchmark::$times[$timer_name] = number_format(microtime(true) - $start_time, 8);
91
    }
92
93
94
95
    /**
96
     * Measure the memory usage by PHP so far.
97
     *
98
     * @param string  $label      The label to show for this time eg "Start of calling Some_Class::some_function"
99
     * @param boolean $output_now whether to echo now, or wait until EEH_Debug_Tools::show_times() is called
100
     * @param bool    $formatted
101
     * @return void
102
     */
103
    public static function measureMemory($label = 'memory usage', $output_now = false, $formatted = true)
104
    {
105
        if (Benchmark::doNotRun()) {
106
            return;
107
        }
108
        $memory_used = Benchmark::convert(memory_get_usage(true));
109
        Benchmark::$memory_usage[$label] = $memory_used;
110
        if ($output_now) {
111
            echo $formatted
112
                ? "<br>{$label} : {$memory_used}"
113
                : "\n {$label} : {$memory_used}";
114
        }
115
    }
116
117
118
119
    /**
120
     * will display the benchmarking results at shutdown
121
     *
122
     * @param bool $formatted
123
     * @return void
124
     */
125
    public static function displayResultsAtShutdown($formatted = true)
126
    {
127
        add_action(
128
            'shutdown',
129
            function () use ($formatted) {
130
                Benchmark::displayResults(true, $formatted);
131
            }
132
        );
133
    }
134
135
136
137
    /**
138
     * will display the benchmarking results at shutdown
139
     *
140
     * @param string $filepath
141
     * @param bool   $formatted
142
     * @param bool   $append
143
     * @return void
144
     */
145
    public static function writeResultsAtShutdown($filepath = '', $formatted = true, $append = true)
146
    {
147
        add_action(
148
            'shutdown',
149
            function () use ($filepath, $formatted, $append) {
150
                Benchmark::writeResultsToFile($filepath, $formatted, $append);
151
            }
152
        );
153
    }
154
155
156
157
    /**
158
     * @param bool $formatted
159
     * @return string
160
     */
161
    private static function generateResults($formatted = true)
162
    {
163
        if (Benchmark::doNotRun()) {
164
            return '';
165
        }
166
        $output = '';
167
        if (! empty(Benchmark::$times)) {
168
            $total = 0;
169
            $output .= $formatted
170
                ? '<span style="color:#999999; font-size:.8em;">( time in milliseconds )</span><br />'
171
                : '';
172
            foreach (Benchmark::$times as $timer_name => $total_time) {
173
                $output .= Benchmark::formatTime($timer_name, $total_time, $formatted);
174
                $output .= $formatted ? '<br />'  : "\n";
175
                $total += $total_time;
176
            }
177
            if($formatted) {
178
                $output .= '<br />';
179
                $output .= '<h4>TOTAL TIME</h4>';
180
                $output .= Benchmark::formatTime('', $total, $formatted);
181
                $output .= '<span style="color:#999999; font-size:.8em;"> milliseconds</span><br />';
182
                $output .= '<br />';
183
                $output .= '<h5>Performance scale (from best to worse)</h5>';
184
                $output .= '<span style="color:mediumpurple">Like wow! How about a Scooby snack?</span><br />';
185
                $output .= '<span style="color:deepskyblue">Like...no way man!</span><br />';
186
                $output .= '<span style="color:limegreen">Like...groovy!</span><br />';
187
                $output .= '<span style="color:gold">Ruh Oh</span><br />';
188
                $output .= '<span style="color:darkorange">Zoinks!</span><br />';
189
                $output .= '<span style="color:red">Like...HEEELLLP</span><br />';
190
            }
191
        }
192
        if (! empty(Benchmark::$memory_usage)) {
193
            $output .= $formatted
194
                ? '<h5>Memory</h5>' . implode('<br />', Benchmark::$memory_usage)
195
                : implode("\n", Benchmark::$memory_usage);
196
        }
197
        if (empty($output)) {
198
            return '';
199
        }
200
        $output = $formatted
201
            ? '<div style="border:1px solid #dddddd; background-color:#ffffff;'
202
              . (is_admin()
203
                ? ' margin:2em 2em 2em 180px;'
204
                : ' margin:2em;')
205
              . ' padding:2em;">'
206
              . '<h4>BENCHMARKING</h4>'
207
              . $output
208
              . '</div>'
209
            : $output;
210
        return $output;
211
    }
212
213
214
215
    /**
216
     * @param bool $echo
217
     * @param bool $formatted
218
     * @return string
219
     */
220
    public static function displayResults($echo = true, $formatted = true)
221
    {
222
        $results = Benchmark::generateResults($formatted);
223
        if ($echo) {
224
            echo $results;
225
            $results = '';
226
        }
227
        return $results;
228
    }
229
230
231
232
    /**
233
     * @param string $filepath
234
     * @param bool   $formatted
235
     * @param bool   $append
236
     */
237
    public static function writeResultsToFile($filepath = '', $formatted = true, $append = true)
238
    {
239
        $filepath = ! empty($filepath) && is_readable(dirname($filepath))
240
            ? $filepath
241
            : '';
242
        if( empty($filepath)) {
243
            $filepath = EVENT_ESPRESSO_UPLOAD_DIR . 'logs/benchmarking-' . date('Y-m-d') . '.html';
244
        }
245
        file_put_contents(
246
            $filepath,
247
            "\n" . date('Y-m-d H:i:s') . Benchmark::generateResults($formatted),
248
            $append ? FILE_APPEND | LOCK_EX : LOCK_EX
249
        );
250
    }
251
252
253
254
    /**
255
     * Converts a measure of memory bytes into the most logical units (eg kb, mb, etc)
256
     *
257
     * @param int $size
258
     * @return string
259
     */
260
    public static function convert($size)
261
    {
262
        $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
263
        return round(
264
            $size / pow(1024, $i = floor(log($size, 1024))),
265
            2
266
        ) . ' ' . $unit[absint($i)];
267
    }
268
269
270
271
    /**
272
     * @param string $timer_name
273
     * @param float  $total_time
274
     * @param bool   $formatted
275
     * @return string
276
     */
277
    public static function formatTime($timer_name, $total_time, $formatted = true)
278
    {
279
        $total_time *= 1000;
280
        switch ($total_time) {
281
            case $total_time > 12500 :
282
                $color = 'red';
283
                $bold = 'bold';
284
                break;
285
            case $total_time > 2500 :
286
                $color = 'darkorange';
287
                $bold = 'bold';
288
                break;
289
            case $total_time > 500 :
290
                $color = 'gold';
291
                $bold = 'bold';
292
                break;
293
            case $total_time > 100 :
294
                $color = 'limegreen';
295
                $bold = 'normal';
296
                break;
297
            case $total_time > 20 :
298
                $color = 'deepskyblue';
299
                $bold = 'normal';
300
                break;
301
            default :
302
                $color = 'mediumpurple';
303
                $bold = 'normal';
304
                break;
305
        }
306
        return $formatted
307
            ? '<span style="min-width: 10px; margin:0 1em; color:'
308
               . $color
309
               . '; font-weight:'
310
               . $bold
311
               . '; font-size:1.2em;">'
312
               . str_pad(number_format($total_time, 3), 9, '0', STR_PAD_LEFT)
313
               . '</span> '
314
               . $timer_name
315
            :  str_pad(number_format($total_time, 3), 9, '0', STR_PAD_LEFT);
316
    }
317
318
319
320
}
321