Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'); | ||
} | ||
} |