Completed
Push — master ( f9a123...73c14a )
by Alec
18:36
created

BenchmarkReport::extractDataFrom()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 11
ccs 2
cts 2
cp 1
rs 9.9666
cc 2
nc 2
nop 1
crap 2
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Tools\Reports;
4
5
use AlecRabbit\Reports\Core\AbstractReport;
6
use AlecRabbit\Reports\Core\AbstractReportable;
7
use AlecRabbit\Tools\Benchmark;
8
use AlecRabbit\Tools\Internal\BenchmarkFunction;
9
use AlecRabbit\Tools\Internal\BenchmarkRelative;
10
use AlecRabbit\Tools\Reports\Contracts\BenchmarkReportInterface;
11
use AlecRabbit\Tools\Traits\BenchmarkFields;
12
use const AlecRabbit\Traits\Constants\DEFAULT_NAME;
13
14
class BenchmarkReport extends AbstractReport implements BenchmarkReportInterface
15
{
16
    use BenchmarkFields;
17
18
    /** {@inheritDoc}
19
     * @throws \Exception
20
     */
21 10
    protected function extractDataFrom(AbstractReportable $reportable = null): void
22
    {
23
        if ($reportable instanceof Benchmark) {
24 10
            $this->added = $reportable->getAdded();
25
            $this->benchmarked = $reportable->getBenchmarked();
26
            $this->memoryUsageReport = $reportable->getMemoryUsageReport();
27
            $this->doneIterations = $reportable->getDoneIterations();
28
            $this->doneIterationsCombined = $reportable->getDoneIterationsCombined();
29
            $this->functions = $this->updateFunctions($reportable->getFunctions());
30
            $this->timer = $reportable->getTimer();
31
            $this->showReturns = $reportable->isShowReturns();
32
        }
33 21
    }
34
35 21
    /**
36 20
     * @param array $functions
37 20
     * @return array
38 20
     */
39 20
    private function updateFunctions(array $functions): array
40 20
    {
41 20
        $averages = $this->computeAverages($functions);
42 20
        $relatives = $this->computeRelatives($averages);
43 20
        $updatedFunctions = [];
44
        if (!empty($relatives)) {
45 1
            $rank = 0;
46
            foreach ($relatives as $name => $relative) {
47 20
                $function = $functions[$name] ?? null;
48
                $average = $averages[$name] ?? null;
49
                if (null !== $function && null !== $average) {
50
                    $function->setBenchmarkRelative(
51
                        new BenchmarkRelative(++$rank, (float)$relative - 1, (float)$average)
52
                    );
53
                }
54 20
                unset($functions[$name]);
55
                $updatedFunctions[$name] = $function;
56 20
            }
57 20
        }
58 20
        foreach ($functions as $name => $function) {
59 20
            $updatedFunctions[$name] = $function;
60 15
        }
61 15
        return $updatedFunctions;
62 15
    }
63 15
64 15
    /**
65 15
     * @param array $functions
66 15
     * @return array
67
     */
68
    private function computeAverages(array $functions): array
69 15
    {
70 15
        $averages = [];
71
        /** @var BenchmarkFunction $f */
72
        foreach ($functions as $f) {
73 20
            $timer = $f->getTimer();
74 7
            if ((DEFAULT_NAME !== $name = $timer->getName())
75
                && 0.0 !== $avg = $timer->getAverageValue()) {
76 20
                $averages[$name] = $avg;
77
            }
78
        }
79
        return $averages;
80
    }
81
82
    private function computeRelatives(array $averages): array
83 20
    {
84
        $rel = [];
85 20
        if (!empty($averages)) {
86
            $min = min($averages);
87 20
88 15
            foreach ($averages as $name => $average) {
89 15
                $rel[$name] = $average / $min;
90 15
            }
91 15
            asort($rel);
92
        }
93
        return $rel;
94 20
    }
95
96
    /** {@inheritdoc} */
97 20
    public function showReturns(): BenchmarkReportInterface
98
    {
99 20
        $this->showReturns = true;
100 20
        foreach ($this->functions as $function) {
101 15
            $function->setShowReturns($this->showReturns);
102
        }
103 15
        return $this;
104 15
    }
105
}
106