View source
<?php
namespace Drupal\markdown;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\ToStringTrait;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class MarkdownBenchmarkAverages {
use DependencySerializationTrait;
use StringTranslationTrait;
use ToStringTrait;
protected static $renderer;
protected $fallbackBenchmark;
protected $iterationCount = 10;
protected $benchmarks = [];
public function __construct($iteration_count = 10, MarkdownBenchmark $fallback_benchmark = NULL) {
$this->iterationCount = $iteration_count;
$this->fallbackBenchmark = $fallback_benchmark;
}
public static function create($iteration_count = 10, MarkdownBenchmark $fallback = NULL) {
return new static($iteration_count, $fallback);
}
public function build($type = 'total') {
if (!$this
->hasBenchmarks()) {
$build = MarkdownBenchmark::invalid();
$title = $this
->t('No available benchmark tests.');
}
else {
$build = $this
->getAverage($type);
$iterations = $this
->getIterationCount() > 1 ? new FormattableMarkup('(@count<em>𝒙</em>) ', [
'@count' => $this
->getIterationCount(),
]) : '';
$variables = [
'@iterations' => $iterations,
];
if ($type !== 'all') {
$variables += [
'@parsed' => $this
->getAverage('parsed', TRUE),
'@rendered' => $this
->getAverage('rendered', TRUE),
'@total' => $this
->getAverage('total', TRUE),
];
}
switch ($type) {
case 'all':
$title = $this
->t('@iterationsParsed / Rendered / Total', $variables);
break;
case 'parsed':
$title = $this
->t('@iterationsParsed (rendered @rendered, total @total)', $variables);
break;
case 'rendered':
$title = $this
->t('@iterationsRendered (parsed @parsed, total @total)', $variables);
break;
default:
$title = $this
->t('@iterationsTotal (parsed @parsed, rendered @rendered)', $variables);
break;
}
}
$build['#attributes']['data-toggle'] = 'tooltip';
$build['#attributes']['data-placement'] = 'bottom';
$build['#attributes']['title'] = $title;
return $build;
}
public function iterate(callable $callback, array $args = []) {
$this->benchmarks = [];
for ($i = 0; $i < $this->iterationCount; $i++) {
$benchmarks = (array) call_user_func_array($callback, $args);
foreach ($benchmarks as $benchmark) {
if (!$benchmark instanceof MarkdownBenchmark) {
throw new \InvalidArgumentException(sprintf('The provided callback must return an instance of \\Drupal\\markdown\\MarkdownBenchmark, got "%s" instead.', (string) $benchmark));
}
if ($this->iterationCount > 1 && $i < $this->iterationCount - 1) {
$benchmark
->clearResult();
}
}
$this->benchmarks = array_merge($this->benchmarks, $benchmarks);
}
return $this;
}
public function getAverage($type = 'total', $render = FALSE) {
$build = [
'#theme' => 'item_list__markdown_benchmark_average',
'#items' => [],
'#attributes' => [
'class' => [
'markdown-benchmark-average',
"markdown-benchmark-average--{$type}",
],
],
'#context' => [
'type' => $type,
],
];
if ($type === 'all') {
$build['#items'] = [
[
'data' => $this
->getAverage('parsed', 'all'),
],
[
'data' => $this
->getAverage('rendered', 'all'),
],
[
'data' => $this
->getAverage('total', 'all'),
],
];
return $build;
}
$benchmarks = $this
->getBenchmarks($type);
if (!$benchmarks) {
return [];
}
$last = array_slice($benchmarks, -1, 1)[0];
$result = $last
->getResult();
if (count($benchmarks) === 1) {
$start = $last
->getStart();
$end = $last
->getEnd();
}
else {
$ms = array_map(function ($benchmark) {
return $benchmark
->getMilliseconds(FALSE);
}, $benchmarks);
$averaged_ms = array_sum($ms) / count($ms);
$start = microtime(TRUE);
$end = $start + $averaged_ms / 1000;
}
$average = MarkdownBenchmark::create('average', $start, $end, $result)
->build();
if ($render === 'all') {
return $average;
}
$build['#items'][] = [
'data' => $average,
];
return $render ? $this
->renderer()
->renderPlain($build) : $build;
}
public function getBenchmarks($type = NULL) {
if ($type === NULL) {
return array_values($this->benchmarks);
}
return array_values(array_filter($this->benchmarks, function ($benchmark) use ($type) {
return $benchmark
->getType() === $type;
}));
}
public function getFallbackBenchmark() {
if ($this->fallbackBenchmark === NULL) {
$this->fallbackBenchmark = MarkdownBenchmark::create('fallback', NULL, NULL, $this
->t('N/A'));
}
return $this->fallbackBenchmark;
}
public function getLastBenchmark($type = 'total') {
$benchmarks = $this
->getBenchmarks($type);
return array_pop($benchmarks) ?: $this
->getFallbackBenchmark();
}
public function getIterationCount() {
return $this->iterationCount;
}
public function hasBenchmarks() {
return !!$this->benchmarks;
}
public function render($type = 'total') {
$build = $this
->build($type);
return $this
->renderer()
->renderPlain($build);
}
protected function renderer() {
if (static::$renderer === NULL) {
static::$renderer = \Drupal::service('renderer');
}
return static::$renderer;
}
}