Passed
Push — master ( af844d...2f21b7 )
by Thomas
14:05
created

src/Benchmark.php (3 issues)

1
<?php
2
3
namespace LeKoala\DevToolkit;
4
5
use Psr\Log\LoggerInterface;
6
use LeKoala\Base\Helpers\ClassHelper;
7
use SilverStripe\Core\Injector\Injector;
8
9
class Benchmark
10
{
11
    /**
12
     * @return \Monolog\Logger
13
     */
14
    public static function getLogger()
15
    {
16
        $parts = explode("\\", get_called_class());
17
        $class = array_pop($parts);
18
        return Injector::inst()->get(LoggerInterface::class)->withName(ClassHelper::getClassWithoutNamespace($class));
19
    }
20
21
    /**
22
     * A dead simple benchmark function
23
     *
24
     * Usage : bm(function() { // Insert here the code to benchmark });
25
     * Alternative usage : bm() ; // Code to test ; bm();
26
     *
27
     * @param callable $cb
28
     * @return void
29
     */
30
    public static function run($cb = null)
31
    {
32
        $data = self::benchmark($cb);
33
        if (!$data) {
0 ignored issues
show
The condition $data is always false.
Loading history...
34
            return;
35
        }
36
        printf("It took %s seconds and used %s memory", $data['time'], $data['memory']);
37
        die();
38
    }
39
40
    /**
41
     * @param null|callable $cb
42
     * @return false|array{'time': string, 'memory': string}
43
     */
44
    protected static function benchmark($cb = null)
45
    {
46
        static $data = null;
47
48
        // No callback scenario
49
        if ($cb === null) {
50
            if ($data === null) {
51
                $data = [
52
                    'startTime' => microtime(true),
53
                    'startMemory' => memory_get_usage(),
54
                ];
55
                // Allow another call
56
                return false;
57
            } else {
58
                $startTime = $data['startTime'];
59
                $startMemory = $data['startMemory'];
60
61
                // Clear for future calls
62
                $data = null;
63
            }
64
        } else {
65
            $startTime = microtime(true);
66
            $startMemory = memory_get_usage();
67
68
            $cb();
69
        }
70
71
        $endTime = microtime(true);
72
        $endMemory = memory_get_usage();
73
74
        $time = sprintf("%.6f", $endTime - $startTime);
75
        $memory = self::bytesToHuman($endMemory - $startMemory);
76
77
        return [
78
            'time' => $time,
79
            'memory' => $memory,
80
        ];
81
    }
82
83
    protected static function bytesToHuman(float $bytes, int $decimals = 2): string
0 ignored issues
show
The parameter $decimals is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

83
    protected static function bytesToHuman(float $bytes, /** @scrutinizer ignore-unused */ int $decimals = 2): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
84
    {
85
        if ($bytes == 0) {
86
            return "0.00 B";
87
        }
88
        $e = floor(log($bytes, 1024));
89
        return round($bytes / pow(1024, $e), 2) . ['B', 'KB', 'MB', 'GB', 'TB', 'PB'][$e];
90
    }
91
92
    /**
93
     * @param string $name
94
     * @param null|callable $cb
95
     * @return void
96
     */
97
    public static function log(string $name, $cb = null): void
98
    {
99
        $data = self::benchmark($cb);
100
        if (!$data) {
0 ignored issues
show
The condition $data is always false.
Loading history...
101
            return;
102
        }
103
104
        $time = $data['time'];
105
        $memory = $data['memory'];
106
107
        self::getLogger()->debug("$name : $time seconds and $memory memory.");
108
    }
109
}
110