Completed
Push — develop ( f10e50...4f888d )
by Alec
03:20
created

Benchmark::withComment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: alec
4
 * Date: 29.11.18
5
 * Time: 11:04
6
 */
7
8
namespace AlecRabbit\Tools;
9
10
use AlecRabbit\Rewindable;
11
use AlecRabbit\Tools\Contracts\BenchmarkInterface;
12
use AlecRabbit\Tools\Internal\BenchmarkedFunction;
13
use AlecRabbit\Tools\Reports\Contracts\ReportableInterface;
14
use AlecRabbit\Tools\Reports\Traits\Reportable;
15
use AlecRabbit\Tools\Traits\BenchmarkFields;
16
17
class Benchmark implements BenchmarkInterface, ReportableInterface
18
{
19
    use BenchmarkFields, Reportable;
20
21
    /** @var int */
22
    private $namingIndex = 0;
23
    /** @var Rewindable */
24
    private $iterations; // todo rename field
25
    /** @var null|string */
26
    private $comment;
27
28 2
    public function __construct(int $iterations = 1000)
29
    {
30 2
        $this->iterations =
31 2
            new Rewindable(
32
                function (int $iterations, int $i = 1): \Generator {
33 1
                    while ($i <= $iterations) {
34 1
                        yield $i++;
35
                    }
36 2
                },
37 2
                $iterations
38
            );
39 2
        $this->profiler = new Profiler();
40 2
    }
41
42
    /**
43
     * Launch benchmarking
44
     */
45 1
    public function compare(): void
46
    {
47
        /** @var  BenchmarkedFunction $f */
48 1
        foreach ($this->functions as $name => $f) {
49 1
            $this->profiler->timer($name)->start();
50 1
            $function = $f->getFunction();
51 1
            $args = $f->getArgs();
52 1
            foreach ($this->iterations as $iteration) {
53
                /** @noinspection VariableFunctionsUsageInspection */
54
                /** @noinspection DisconnectedForeachInstructionInspection */
55 1
                \call_user_func($function, ...$args);
56 1
                $this->profiler->timer($name)->check($iteration);
57 1
                ++$this->iteration;
58
            }
59
        }
60 1
    }
61
62
    /**
63
     * @param callable $func
64
     * @param mixed ...$args
65
     */
66 1
    public function addFunction($func, ...$args): void
67
    {
68 1
        if (!\is_callable($func, false, $name)) {
69
            throw new \InvalidArgumentException('Function must be callable.');
70
        }
71 1
        $function = new BenchmarkedFunction($func, $name, $this->namingIndex++, $args, $this->comment);
72 1
        $this->comment = null;
73
74 1
        $this->functions[$function->getEnumeratedName()] = $function;
75 1
    }
76
77
    /**
78
     * @param string $name
79
     * @return Benchmark
80
     */
81 1
    public function withComment(string $name): self
82
    {
83 1
        $this->comment = $name;
84 1
        return $this;
85
    }
86
87
    /**
88
     * @return Profiler
89
     */
90 2
    public function getProfiler(): Profiler
91
    {
92 2
        return $this->profiler;
93
    }
94
95 2
    protected function prepareForReport(): void
96
    {
97 2
        $this->getProfiler()->report();
98 2
    }
99
}
100