Skip to content

Commit

Permalink
Merge 55b960e into 5a294f1
Browse files Browse the repository at this point in the history
  • Loading branch information
kelunik committed Oct 10, 2019
2 parents 5a294f1 + 55b960e commit 1b3e2fe
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
23 changes: 23 additions & 0 deletions examples/timing.php
@@ -0,0 +1,23 @@
<?php /** @noinspection ForgottenDebugOutputInspection */

use Amp\Timing;

require __DIR__ . '/../vendor/autoload.php';

$timing = new Timing;
$timing->start('amphp.http-client.request');
\usleep(\random_int(1, 10) * 1000);
$timing->start('amphp.dns.resolution');
\usleep(\random_int(1, 10) * 1000);
$timing->end('amphp.dns.resolution');
\usleep(\random_int(1, 10) * 1000);
$timing->start('amphp.socket.connect');
\usleep(\random_int(1, 10) * 1000);
$timing->end('amphp.socket.connect');
\usleep(\random_int(1, 10) * 1000);

var_dump($timing);

$timing->end('amphp.http-client.request');

var_dump($timing);
70 changes: 70 additions & 0 deletions lib/Timing.php
@@ -0,0 +1,70 @@
<?php

namespace Amp;

use function Amp\Internal\getCurrentTime;

final class Timing
{
private $timings = [];

public function start(string $key)
{
if (isset($this->timings[$key])) {
$time = getCurrentTime() - $this->timings[$key][0];
throw new \Error("Timer '$key' has already been started $time milliseconds ago");
}

$this->timings[$key] = [getCurrentTime()];
}

public function end(string $key)
{
$now = getCurrentTime();

if (!isset($this->timings[$key])) {
throw new \Error("Timer '$key' has not been started, yet");
}

if (\count($this->timings[$key]) !== 1) {
$time = $now - $this->timings[$key][1];
throw new \Error("Timer '$key' has already been stopped $time milliseconds ago");
}

$this->timings[$key][1] = $now;
}

public function getDuration(string $key): int
{
if (!isset($this->timings[$key])) {
throw new \Error("Timer '$key' has not been started, yet");
}

if (\count($this->timings[$key]) === 1) {
return getCurrentTime() - $this->timings[$key][0];
}

return $this->timings[$key][1] - $this->timings[$key][0];
}

/** @return string[] */
public function getKeys(): array
{
return \array_map('\strval', \array_keys($this->timings));
}

public function __debugInfo(): array
{
$entries = [];

foreach ($this->timings as $key => $timings) {
if (\count($timings) === 1) {
$entries[$key] = $this->getDuration($key) . ' ms (ongoing)';
} else {
$entries[$key] = $this->getDuration($key) . ' ms';
}
}

return $entries;
}
}
53 changes: 53 additions & 0 deletions lib/TimingTest.php
@@ -0,0 +1,53 @@
<?php

namespace Amp;

use PHPUnit\Framework\TestCase;

class TimingTest extends TestCase
{
public function testTiming()
{
$timing = new Timing;
$timing->start('foo');
\usleep(5000);
$timing->end('foo');

$this->assertGreaterThanOrEqual(5, $timing->getDuration('foo'));
}

public function testTimingNotStarted()
{
$this->expectException(\Error::class);

$timing = new Timing;
$timing->end('foo');
}

public function testTimingAlreadyStarted()
{
$this->expectException(\Error::class);

$timing = new Timing;
$timing->start('foo');
$timing->start('foo');
}

public function testTimingAlreadyEnded()
{
$this->expectException(\Error::class);

$timing = new Timing;
$timing->start('foo');
$timing->end('foo');
$timing->end('foo');
}

public function testTimingNonExistent()
{
$this->expectException(\Error::class);

$timing = new Timing;
$timing->getDuration('foo');
}
}

0 comments on commit 1b3e2fe

Please sign in to comment.