Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: phpunit
name: tests

on: [ push ]

Expand Down
6 changes: 4 additions & 2 deletions src/Benchmark.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function iterations(int $count): self

public function round(?int $precision): self
{
$this->view->setRound($precision);
$this->transformer->round($precision);

return $this;
}
Expand Down Expand Up @@ -109,7 +109,7 @@ public function toData(): array

public function toConsole(): void
{
$table = $this->transformer->show(
$table = $this->transformer->toTable(
$this->toData()
);

Expand All @@ -125,6 +125,8 @@ public function assert(): AssertService

protected function withProgress(array $callbacks, int $count): void
{
$this->view->emptyLine();

$bar = $this->view->progressBar()->create($count);

$this->chunks($callbacks, $bar);
Expand Down
1 change: 1 addition & 0 deletions src/Services/MemoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
class MemoryService
{
protected array $sizes = [
'TB' => 1024 * 1024 * 1024 * 1024,
'GB' => 1024 * 1024 * 1024,
'MB' => 1024 * 1024,
'KB' => 1024,
Expand Down
59 changes: 4 additions & 55 deletions src/Services/ViewService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,21 @@

namespace DragonCode\Benchmark\Services;

use DragonCode\Benchmark\View\LineView;
use DragonCode\Benchmark\View\ProgressBarView;
use DragonCode\Benchmark\View\TableView;

use function is_array;
use function is_numeric;
use function round;
use function sprintf;

class ViewService
{
protected ?int $roundPrecision = null;

public function __construct(
protected MemoryService $memory = new MemoryService,
protected TableView $table = new TableView,
protected ProgressBarView $progressBar = new ProgressBarView,
protected LineView $line = new LineView,
) {}

public function setRound(?int $precision): void
{
$this->roundPrecision = $precision;
}

public function table(array $data): void
{
$this->table->show(
$this->appendMs($data)
);
$this->table->show($data);
}

public function progressBar(): ProgressBarView
Expand All @@ -41,44 +28,6 @@ public function progressBar(): ProgressBarView

public function emptyLine(int $count = 1): void
{
echo "\r";
}

protected function appendMs(array $data): array
{
foreach ($data as &$values) {
foreach ($values as $key => &$value) {
if ($key === '#' || ! is_array($value)) {
continue;
}

$time = $this->roundTime($value['time']);
$ram = $this->roundRam($value['ram'] ?? null);

$value = ! empty($ram)
? sprintf('%s ms - %s', $time, $ram)
: sprintf('%s ms', $time);
}
}

return $data;
}

protected function roundTime(float $value): float
{
if (is_numeric($this->roundPrecision)) {
return round($value, $this->roundPrecision);
}

return $value;
}

protected function roundRam(float|int|null $bytes): ?string
{
if ($bytes !== null) {
return $this->memory->format((int) $bytes);
}

return null;
$this->line->newLine($count);
}
}
87 changes: 78 additions & 9 deletions src/Transformers/ResultTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,100 @@
namespace DragonCode\Benchmark\Transformers;

use DragonCode\Benchmark\Data\MetricData;
use DragonCode\Benchmark\Services\MemoryService;

use function sprintf;
use function array_keys;
use function asort;

class ResultTransformer
{
protected ?int $precision = null;

protected array $table = [
['#' => 'min'],
['#' => 'max'],
['#' => 'avg'],
['#' => 'total'],
[null],
['#' => 'order'],
];

public function __construct(
protected MemoryService $memory = new MemoryService,
) {}

public function round(?int $precision): void
{
$this->precision = $precision;
}

/**
* @param \DragonCode\Benchmark\Data\ResultData[] $collection
*/
public function show(array $collection): array
public function toTable(array $collection): array
{
$table = [];
$table = $this->map($this->table, $collection);

return $this->order($table, $collection);
}

/**
* @param \DragonCode\Benchmark\Data\ResultData[] $collection
*/
protected function map(array $table, array $collection): array
{
foreach ($collection as $key => $item) {
$table['#'][] = $key;
$table['min'][] = $this->value($item->min);
$table['max'][] = $this->value($item->max);
$table['avg'][] = $this->value($item->avg);
$table['total'][] = $this->value($item->total);
$table[0][$key] = $this->value($item->min);
$table[1][$key] = $this->value($item->max);
$table[2][$key] = $this->value($item->avg);
$table[3][$key] = $this->value($item->total);
$table[5][$key] = 0;
}

return $table;
}

/**
* @param \DragonCode\Benchmark\Data\ResultData[] $collection
*/
protected function order(array $table, array $collection): array
{
$values = [];

foreach ($collection as $key => $item) {
$values[$key] = $item->avg->time;
}

asort($values, SORT_NUMERIC);

foreach (array_keys($values) as $index => $key) {
$table[5][$key] = $index + 1;
}

return $table;
}

protected function value(MetricData $metric): string
{
return sprintf('%d ms - %s b', $metric->time, $metric->memory);
$time = $this->time($metric->time);
$memory = $this->memory($metric->memory);

return $memory
? sprintf('%s ms - %s', $time, $memory)
: sprintf('%s ms', $time);
}

protected function time(float $value): float
{
if ($this->precision === null) {
return $value;
}

return round($value, $this->precision);
}

protected function memory(float|int $bytes): string
{
return $this->memory->format((int) $bytes);
}
}
24 changes: 24 additions & 0 deletions src/View/LineView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace DragonCode\Benchmark\View;

class LineView extends View
{
public function newLine(int $count = 1): void
{
for ($i = 0; $i < $count; $i++) {
$this->writeLine('');
}
}

protected function stream()
{
if (static::$stream === null) {
static::$stream = fopen('php://stdout', 'wb');
}

return static::$stream;
}
}
4 changes: 3 additions & 1 deletion src/View/ProgressBarView.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class ProgressBarView extends View

protected int $total = 100;

protected ?bool $canShow = null;

public function create(int $total): static
{
$this->total = max(1, $total);
Expand Down Expand Up @@ -61,7 +63,7 @@ protected function display(): void
protected function stream()
{
if (static::$stream === null) {
static::$stream = fopen('php://stderr', 'w');
static::$stream = fopen('php://stderr', 'wb');
}

return static::$stream;
Expand Down
8 changes: 7 additions & 1 deletion src/View/TableView.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public function show(array $data): void
$this->writeLine($this->separator($widths));

foreach ($data as $row) {
if ($row === [null]) {
$this->writeLine($this->separator($widths));

continue;
}

$this->writeLine($this->formatRow(array_values($row), $widths));
}

Expand Down Expand Up @@ -72,7 +78,7 @@ protected function formatRow(array $values, array $widths): string
protected function stream()
{
if (static::$stream === null) {
static::$stream = fopen('php://stdout', 'w');
static::$stream = fopen('php://stdout', 'wb');
}

return static::$stream;
Expand Down
10 changes: 10 additions & 0 deletions tests/.pest/snapshots/Unit/Result/ToConsoleTest/output.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
+-------+----------------------------+--------------------------+
| # | 0 | 1 |
+-------+----------------------------+--------------------------+
| min | 4.56789012 ms - 50 bytes | 1.23456789 ms - 20 bytes |
| max | 6.78901234 ms - 70 bytes | 3.45678901 ms - 40 bytes |
| avg | 5.67860123 ms - 60 bytes | 2.3456786 ms - 30 bytes |
| total | 17.03580369 ms - 182 bytes | 7.0370358 ms - 90 bytes |
+-------+----------------------------+--------------------------+
| order | 2 | 1 |
+-------+----------------------------+--------------------------+
26 changes: 26 additions & 0 deletions tests/Fixtures/CollectorFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tests\Fixtures;

use DragonCode\Benchmark\Services\CollectorService;

class CollectorFixture extends CollectorService
{
public function all(): array
{
return [
[
[4.56789012, 50.67890],
[5.67890123, 60.78901],
[6.78901234, 70.89012],
],
[
[1.23456789, 20.12345],
[2.34567890, 30.23456],
[3.45678901, 40.34567],
],
];
}
}
8 changes: 6 additions & 2 deletions tests/Helpers/benchmark.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
declare(strict_types=1);

use DragonCode\Benchmark\Benchmark;
use DragonCode\Benchmark\Services\CollectorService;
use Tests\Fixtures\CollectorFixture;

function benchmark(): Benchmark
function benchmark(bool $customCollector = true): Benchmark
{
return (new Benchmark)->iterations(3);
$collector = $customCollector ? new CollectorFixture : new CollectorService;

return (new Benchmark(collector: $collector))->iterations(3);
}
27 changes: 26 additions & 1 deletion tests/Pest.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
<?php

use DragonCode\Benchmark\View\View;
use PHPUnit\Framework\TestCase;

pest()
->printer()
->compact();

pest()
->extend(TestCase::class)
->in('Unit');
->in('Unit')
->beforeEach(function () {
$reflection = new ReflectionClass(View::class);

$property = $reflection->getProperty('stream');

$property->setValue(null, fopen('php://memory', 'r+b'));
})
->afterEach(function () {
$reflection = new ReflectionClass(View::class);

$property = $reflection->getProperty('stream');

$stream = $property->getValue();

if (is_resource($stream)) {
fclose($stream);
}

$property->setValue(null, null);
});
Loading
Loading