Test Failed
Push — master ( 3fe081...08cc3f )
by Kacper
03:11
created

AnalyzeCommand::avarage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2016, Some right reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp: [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Highlighter\bin\Commands\Benchmark;
17
18
19
use Kadet\Highlighter\Formatter\FormatterInterface;
20
use Kadet\Highlighter\KeyLighter;
21
use Kadet\Highlighter\Language\Language;
22
use Symfony\Component\Console\Command\Command;
23
use Symfony\Component\Console\Helper\Table;
24
use Symfony\Component\Console\Helper\TableCell;
25
use Symfony\Component\Console\Helper\TableSeparator;
26
use Symfony\Component\Console\Input\InputArgument;
27
use Symfony\Component\Console\Input\InputInterface;
28
use Symfony\Component\Console\Input\InputOption;
29
use Symfony\Component\Console\Output\OutputInterface;
30
31
class AnalyzeCommand extends Command
32
{
33
    protected function execute(InputInterface $input, OutputInterface $output)
34
    {
35
        $json = json_decode(file_get_contents($input->getArgument('input')[0]), true);
36
37
        $output->writeln(sprintf(
38
            "Date: <info>%s</info> Formatter: <info>%s</info>, Comment: <info>%s</info>",
39
            date('d.m.Y H:i:s', $json['timestamp']), $json['formatter'], isset($json['comment']) ? $json['comment'] : 'none'
40
        ));
41
42
        $table = new Table($output);
43
44
        $suffix = $input->getOption('relative') ? 'bytes/s' : 'ms';
45
        $table->addRow(['set', "min [$suffix]", "avg [$suffix]", "max [$suffix]", "std dev [$suffix]"]);
46
47
        $summary = [];
48
        foreach ($json['results'] as $file => $data) {
49
            $this->separator($file, $table);
50
51
            foreach ($data['times'] as $set => $times) {
52
                $result = array_map(function ($time) use ($data, $input) {
53
                    return $input->getOption('relative') ? $data['size'] / $time : $time * 1000;
54
                }, $times);
55
56
                $this->entry($result, $set, $table);
57
58
                $summary[$set][] = array_sum($result) / count($result);
59
            }
60
        }
61
62
        if(!$input->hasOption('summary')) {
63
            $table->render();
64
        }
65
66
        $summary = array_filter($summary, function($key) use ($input) {
67
            return fnmatch($input->getOption('summary') ?: '*', $key);
68
        }, ARRAY_FILTER_USE_KEY);
69
70
        $max = max(array_map('strlen', array_keys($summary)));
71
        foreach($summary as $name => $set) {
72
            $output->writeln(sprintf(
73
                "<comment>%s</comment> %s %s",
74
                str_pad($name, $max, ' ', STR_PAD_LEFT),
75
                $this->format($input->getOption('relative') ? array_sum($set) / count($set) : array_sum($set)),
76
                $suffix
77
            ));
78
        }
79
    }
80
81
    protected function separator($file, Table $table)
82
    {
83
        $table->addRows([
84
            new TableSeparator(),
85
            [new TableCell($file, ['colspan' => 5])],
86
            new TableSeparator(),
87
        ]);
88
    }
89
90
    protected function entry($result, $set, Table $table)
91
    {
92
        $min = min($result);
93
        $avg = $this->avarage($result);
94
        $max = max($result);
95
        $dev = $this->stddev($result);
96
97
        $table->addRow([
98
            $set,
99
            $this->format($min),
100
            $this->format($avg),
101
            $this->format($max),
102
            sprintf("%s (%d%%)", $this->format($dev), $dev / $avg * 100),
103
        ]);
104
    }
105
106
    private function format($number)
107
    {
108
        return number_format($number, 2);
109
    }
110
111
    private function avarage(array $result)
112
    {
113
        return array_sum($result) / count($result);
114
    }
115
116
    private function stddev($result)
117
    {
118
        $mean = array_sum($result) / count($result);
119
120
        return sqrt(array_sum(array_map(function ($result) use ($mean) {
121
                return pow($result - $mean, 2);
122
            }, $result)) / count($result));
123
    }
124
125
    protected function configure()
126
    {
127
        $this
128
            ->setName('benchmark:analyze')
129
            ->setDescription('Tests performance of KeyLighter')
130
            ->addArgument('input', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Input JSON file(s)')
131
            ->addOption('relative', 'r', InputOption::VALUE_NONE, 'Show relative times?')
132
            ->addOption('summary', 'u', InputOption::VALUE_OPTIONAL, 'Show summary times?', '*');
133
    }
134
}
135