Completed
Push — master ( dc4b6d...04cf1c )
by Kacper
04:06
created

bin/Commands/Benchmark/RunCommand.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Input\InputArgument;
24
use Symfony\Component\Console\Input\InputInterface;
25
use Symfony\Component\Console\Input\InputOption;
26
use Symfony\Component\Console\Output\OutputInterface;
27
28
class RunCommand extends Command
29
{
30
    const DIRECTORY = "../../../Tests/Samples/";
31
32
    protected function execute(InputInterface $input, OutputInterface $output)
33
    {
34
        $dir = __DIR__ . 'BenchmarkCommand.php/' .static::DIRECTORY;
35
        $iterator = new \RecursiveIteratorIterator(
36
            new \RecursiveDirectoryIterator(
37
                $dir,
38
                \RecursiveDirectoryIterator::SKIP_DOTS | \RecursiveDirectoryIterator::UNIX_PATHS
39
            ), \RecursiveIteratorIterator::LEAVES_ONLY
40
        );
41
42
        $formatter = $input->hasOption('formatter')
43
            ? KeyLighter::get()->getFormatter($input->getOption('formatter'))
44
            : KeyLighter::get()->getDefaultFormatter();
45
46
        $results = [];
47
48
        /** @var \SplFileInfo $file */
49
        foreach ($iterator as $file) {
50
            $shortname = substr($file->getPathname(), strlen($dir));
51
52
            if (!fnmatch($input->getOption('include'), $shortname)) {
53
                $output->writeln(sprintf('Skipping file <info>%s</info>', $shortname), OutputInterface::VERBOSITY_VERBOSE);
54
55
                continue;
56
            }
57
58
            $language = Language::byFilename($file->getFilename());
59
            $source = file_get_contents($file->getPathname());
60
61
            $output->writeln(sprintf(
62
                'File: <info>%s</info> Size: <info>%s</info> Language: <info>%s</info>',
63
                substr($file->getPathname(), strlen($dir)), $file->getSize(), get_class($language)
64
            ), OutputInterface::VERBOSITY_VERBOSE);
65
66
            // Dry run, to include all necessary files.
67
            $this->benchmark($source, $language, $formatter);
68
69
            $intermediate = [];
70
            for($i = $input->getOption('times'); $i > 0; $i--) {
71
                $intermediate = array_merge_recursive($intermediate, $this->benchmark($source, $language, $formatter));
72
73
                if($input->getOption('geshi') && class_exists('GeSHi')) {
74
                    $intermediate['geshi'][] = $this->geshi($source, $file->getExtension());
75
                }
76
            }
77
78
            $results[$shortname] = [
79
                'language' => get_class($language),
80
                'size' => $file->getSize(),
81
                'times' => $intermediate
82
            ];
83
        }
84
85
        $this->output([
86
            'formatter' => get_class($formatter),
87
            'timestamp' => time(),
88
            'system'    => php_uname(),
89
            'comment'   => $input->getOption('comment'),
90
            'results'   => $results
91
        ], $input, $output);
92
    }
93
94
    protected function configure()
95
    {
96
        $this
97
            ->setName('benchmark:run')
98
            ->setDescription('Tests performance of KeyLighter')
99
            ->addOption('times', 't', InputOption::VALUE_OPTIONAL, 'How many times each test will be run', 50)
100
            ->addOption('include', 'i', InputOption::VALUE_OPTIONAL, 'File mask to include', '*')
101
            ->addOption('comment', 'm', InputOption::VALUE_OPTIONAL, 'Comment to include in file')
102
            ->addOption('pretty', 'p', InputOption::VALUE_NONE, 'Pretty print')
103
            ->addOption('geshi', 'g', InputOption::VALUE_NONE, 'Include GeSHi for comparsion')
104
            ->addOption('formatter', 'f', InputOption::VALUE_OPTIONAL, 'Formatter used for benchmark')
105
            ->addArgument('output', InputArgument::OPTIONAL, 'Output file')
106
        ;
107
    }
108
109
    protected function benchmark($source, Language $language, FormatterInterface $formatter, $geshi = null)
0 ignored issues
show
The parameter $geshi is not used and could be removed.

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

Loading history...
110
    {
111
        $tokenization = microtime(true);
112
        $tokens = $language->tokenize($source);
113
        $tokenization = microtime(true) - $tokenization;
114
115
        $parsing = microtime(true);
116
        $parsed = $language->parse($tokens);
117
        $parsing = microtime(true) - $parsing;
118
119
        $formatting = microtime(true);
120
        $formatter->format($parsed);
121
        $formatting = microtime(true) - $formatting;
122
123
        $overall = $tokenization + $parsing + $formatting;
124
        return compact('tokenization', 'parsing', 'formatting', 'overall');
125
    }
126
127
    protected function geshi($source, $language)
128
    {
129
        $geshi = microtime(true);
130
        geshi_highlight($source, $language, null, true);
131
        return microtime(true) - $geshi;
132
    }
133
134
    protected function output($results, InputInterface $input, OutputInterface $output)
135
    {
136
        $result = json_encode($results, $input->getOption('pretty') ? JSON_PRETTY_PRINT : 0);
137
138
        if($input->hasArgument('output')) {
139
            file_put_contents($input->getArgument('output'), $result);
140
        } else {
141
            $output->write($result);
142
        }
143
    }
144
}
145