Disk::render()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace Hyperized\Benchmark\Modules;
5
6
7
use Hyperized\Benchmark\Config\Config;
8
use Hyperized\Benchmark\Generic\Directory;
9
use Hyperized\Benchmark\Generic\Table;
10
use Hyperized\Benchmark\Generic\Visual;
11
12
/**
13
 * Class Disk
14
 * @package Hyperized\Benchmark\Modules
15
 */
16
class Disk
17
{
18
    /**
19
     * @var string
20
     */
21
    private static $path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..';
22
    /**
23
     * @var string
24
     */
25
    private static $tmpDirectory = DIRECTORY_SEPARATOR . 'tmp';
26
    /**
27
     * @var array
28
     */
29
    private static $commonBlockSizesBytes = [
30
        512,
31
        1024,
32
        2048,
33
        4096,
34
        8192,
35
        16384,
36
        32678,
37
        65536,
38
    ];
39
    /**
40
     * @var int
41
     */
42
    private $initial;
43
    /**
44
     * @var
45
     */
46
    private $tmpDirectoryPath;
47
    /**
48
     * @var array
49
     */
50
    private $counterFileCreation = [];
51
    /**
52
     * @var int
53
     */
54
    private $cycles = 1;
55
56
    /**
57
     * Disk constructor.
58
     *
59
     * @param \Hyperized\Benchmark\Config\Config $config
60
     */
61
    public function __construct(Config $config)
62
    {
63
        if ($config->get('benchmark.disk.enabled')) {
64
            $this->cycles = $config->get('benchmark.disk.cycles');
65
            $this->run();
66
            $this->render();
67
        }
68
    }
69
70
    /**
71
     * Run!
72
     */
73
    private function run(): void
74
    {
75
        $this->initial = \time();
76
        $this->tmpDirectoryPath = \realpath(self::$path) . self::$tmpDirectory;
77
78
        try {
79
            // Create subdirectory
80
            Directory::create($this->tmpDirectoryPath);
81
82
            foreach (self::$commonBlockSizesBytes as $bytes) {
83
                $this->counterFileCreation['Run'][$bytes] = 0;
84
            }
85
86
            for ($c = $this->cycles; $c >= 0; $c--) {
87
                // Generate files with different block sizes
88
                foreach (self::$commonBlockSizesBytes as $bytes) {
89
                    $prefix = $this->initial . '_' . $bytes;
90
                    $content = $this->getRandomBytes($bytes);
91
92
                    // Start the timer (measure only disk interaction, not string generation etc)
93
                    $start = \microtime(true);
94
95
                    $file = \tempnam($this->tmpDirectoryPath, $prefix);
96
                    \file_put_contents($file, $content);
97
98
                    // Stop timer & append time to timer array with this block size
99
                    $this->counterFileCreation['Run'][$bytes] += (\microtime(true) - $start);
100
                }
101
            }
102
103
            // Clean up
104
            Directory::removeRecursively($this->tmpDirectoryPath);
105
        } catch (\Exception $e) {
106
            Visual::print($e);
107
        }
108
    }
109
110
    /**
111
     * @param $bytes
112
     *
113
     * @return string
114
     * @throws \Exception
115
     */
116
    private function getRandomBytes($bytes): string
117
    {
118
        return random_bytes($bytes);
119
    }
120
121
    /**
122
     * Render
123
     */
124
    private function render(): void
125
    {
126
        Visual::print('== Disk performance information', "\n");
127
        Visual::print('Results sorted by file size (in bytes) in milliseconds (less is better), for a total of ' . $this->cycles . ' cycles:', "\n");
128
        new Table($this->counterFileCreation);
129
        Visual::print(' ', "\n");
130
    }
131
}