Skip to content

Add support for microseconds in Stopwatch #23223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ private function registerDebugConfiguration(array $config, ContainerBuilder $con
$loader->load('debug_prod.xml');

if (class_exists(Stopwatch::class)) {
$container->register('debug.stopwatch', Stopwatch::class);
$container->register('debug.stopwatch', Stopwatch::class)->addArgument(true);
$container->setAlias(Stopwatch::class, 'debug.stopwatch');
}

Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Stopwatch/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ CHANGELOG
-----

* added the `Stopwatch::reset()` method
* allowed to measure sub-millisecond times by introducing an argument to the
constructor of `Stopwatch`
15 changes: 11 additions & 4 deletions src/Symfony/Component/Stopwatch/Section.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class Section
*/
private $origin;

/**
* @var bool
*/
private $morePrecision;

/**
* @var string
*/
Expand All @@ -41,11 +46,13 @@ class Section
/**
* Constructor.
*
* @param float|null $origin Set the origin of the events in this section, use null to set their origin to their start time
* @param float|null $origin Set the origin of the events in this section, use null to set their origin to their start time
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct($origin = null)
public function __construct($origin = null, $morePrecision = false)
{
$this->origin = is_numeric($origin) ? $origin : null;
$this->morePrecision = $morePrecision;
}

/**
Expand Down Expand Up @@ -74,7 +81,7 @@ public function get($id)
public function open($id)
{
if (null === $session = $this->get($id)) {
$session = $this->children[] = new self(microtime(true) * 1000);
$session = $this->children[] = new self(microtime(true) * 1000, $this->morePrecision);
}

return $session;
Expand Down Expand Up @@ -113,7 +120,7 @@ public function setId($id)
public function startEvent($name, $category)
{
if (!isset($this->events[$name])) {
$this->events[$name] = new StopwatchEvent($this->origin ?: microtime(true) * 1000, $category);
$this->events[$name] = new StopwatchEvent($this->origin ?: microtime(true) * 1000, $category, $this->morePrecision);
}

return $this->events[$name]->start();
Expand Down
13 changes: 11 additions & 2 deletions src/Symfony/Component/Stopwatch/Stopwatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
*/
class Stopwatch
{
/**
* @var bool
*/
private $morePrecision;

/**
* @var Section[]
*/
Expand All @@ -28,9 +33,13 @@ class Stopwatch
*/
private $activeSections;

public function __construct()
/**
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct($morePrecision = false)
{
$this->reset();
$this->morePrecision = $morePrecision;
}

/**
Expand Down Expand Up @@ -162,6 +171,6 @@ public function getSectionEvents($id)
*/
public function reset()
{
$this->sections = $this->activeSections = array('__root__' => new Section('__root__'));
$this->sections = $this->activeSections = array('__root__' => new Section('__root__', $this->morePrecision));
}
}
17 changes: 12 additions & 5 deletions src/Symfony/Component/Stopwatch/StopwatchEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ class StopwatchEvent
*/
private $category;

/**
* @var bool
*/
private $morePrecision;

/**
* @var float[]
*/
Expand All @@ -41,15 +46,17 @@ class StopwatchEvent
/**
* Constructor.
*
* @param float $origin The origin time in milliseconds
* @param string|null $category The event category or null to use the default
* @param float $origin The origin time in milliseconds
* @param string|null $category The event category or null to use the default
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*
* @throws \InvalidArgumentException When the raw time is not valid
*/
public function __construct($origin, $category = null)
public function __construct($origin, $category = null, $morePrecision = false)
{
$this->origin = $this->formatTime($origin);
$this->category = is_string($category) ? $category : 'default';
$this->morePrecision = $morePrecision;
}

/**
Expand Down Expand Up @@ -97,7 +104,7 @@ public function stop()
throw new \LogicException('stop() called but start() has not been called before.');
}

$this->periods[] = new StopwatchPeriod(array_pop($this->started), $this->getNow());
$this->periods[] = new StopwatchPeriod(array_pop($this->started), $this->getNow(), $this->morePrecision);

return $this;
}
Expand Down Expand Up @@ -177,7 +184,7 @@ public function getDuration()

for ($i = 0; $i < $left; ++$i) {
$index = $stopped + $i;
$periods[] = new StopwatchPeriod($this->started[$index], $this->getNow());
$periods[] = new StopwatchPeriod($this->started[$index], $this->getNow(), $this->morePrecision);
}

$total = 0;
Expand Down
17 changes: 9 additions & 8 deletions src/Symfony/Component/Stopwatch/StopwatchPeriod.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@ class StopwatchPeriod
/**
* Constructor.
*
* @param int $start The relative time of the start of the period (in milliseconds)
* @param int $end The relative time of the end of the period (in milliseconds)
* @param int|float $start The relative time of the start of the period (in milliseconds)
* @param int|float $end The relative time of the end of the period (in milliseconds)
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct($start, $end)
public function __construct($start, $end, $morePrecision = false)
{
$this->start = (int) $start;
$this->end = (int) $end;
$this->start = $morePrecision ? (float) $start : (int) $start;
$this->end = $morePrecision ? (float) $end : (int) $end;
$this->memory = memory_get_usage(true);
}

/**
* Gets the relative time of the start of the period.
*
* @return int The time (in milliseconds)
* @return int|float The time (in milliseconds)
*/
public function getStartTime()
{
Expand All @@ -48,7 +49,7 @@ public function getStartTime()
/**
* Gets the relative time of the end of the period.
*
* @return int The time (in milliseconds)
* @return int|float The time (in milliseconds)
*/
public function getEndTime()
{
Expand All @@ -58,7 +59,7 @@ public function getEndTime()
/**
* Gets the time spent in this period.
*
* @return int The period duration (in milliseconds)
* @return int|float The period duration (in milliseconds)
*/
public function getDuration()
{
Expand Down
67 changes: 67 additions & 0 deletions src/Symfony/Component/Stopwatch/Tests/StopwatchPeriodTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Stopwatch\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Stopwatch\StopwatchPeriod;

class StopwatchPeriodTest extends TestCase
{
/**
* @dataProvider provideTimeValues
*/
public function testGetStartTime($start, $useMorePrecision, $expected)
{
$period = new StopwatchPeriod($start, $start, $useMorePrecision);
$this->assertSame($expected, $period->getStartTime());
}

/**
* @dataProvider provideTimeValues
*/
public function testGetEndTime($end, $useMorePrecision, $expected)
{
$period = new StopwatchPeriod($end, $end, $useMorePrecision);
$this->assertSame($expected, $period->getEndTime());
}

/**
* @dataProvider provideDurationValues
*/
public function testGetDuration($start, $end, $useMorePrecision, $duration)
{
$period = new StopwatchPeriod($start, $end, $useMorePrecision);
$this->assertSame($duration, $period->getDuration());
}

public function provideTimeValues()
{
yield array(0, false, 0);
yield array(0, true, 0.0);
yield array(0.0, false, 0);
yield array(0.0, true, 0.0);
yield array(2.71, false, 2);
yield array(2.71, true, 2.71);
}

public function provideDurationValues()
{
yield array(0, 0, false, 0);
yield array(0, 0, true, 0.0);
yield array(0.0, 0.0, false, 0);
yield array(0.0, 0.0, true, 0.0);
yield array(2, 3.14, false, 1);
yield array(2, 3.14, true, 1.14);
yield array(2.71, 3.14, false, 1);
yield array(2.71, 3.14, true, 0.43);
}
}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy