diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index f3b77f0a12409..a3c92a026be52 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -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'); } diff --git a/src/Symfony/Component/Stopwatch/CHANGELOG.md b/src/Symfony/Component/Stopwatch/CHANGELOG.md index 2a03545ed1b82..36d0c25f1a9f7 100644 --- a/src/Symfony/Component/Stopwatch/CHANGELOG.md +++ b/src/Symfony/Component/Stopwatch/CHANGELOG.md @@ -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` diff --git a/src/Symfony/Component/Stopwatch/Section.php b/src/Symfony/Component/Stopwatch/Section.php index 2337e03140c7f..d4ff9928f83ac 100644 --- a/src/Symfony/Component/Stopwatch/Section.php +++ b/src/Symfony/Component/Stopwatch/Section.php @@ -28,6 +28,11 @@ class Section */ private $origin; + /** + * @var bool + */ + private $morePrecision; + /** * @var string */ @@ -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; } /** @@ -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; @@ -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(); diff --git a/src/Symfony/Component/Stopwatch/Stopwatch.php b/src/Symfony/Component/Stopwatch/Stopwatch.php index 562f220f673b1..cbe08cc7c1f0f 100644 --- a/src/Symfony/Component/Stopwatch/Stopwatch.php +++ b/src/Symfony/Component/Stopwatch/Stopwatch.php @@ -18,6 +18,11 @@ */ class Stopwatch { + /** + * @var bool + */ + private $morePrecision; + /** * @var Section[] */ @@ -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; } /** @@ -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)); } } diff --git a/src/Symfony/Component/Stopwatch/StopwatchEvent.php b/src/Symfony/Component/Stopwatch/StopwatchEvent.php index 16a30db2aa50e..0d20f49b13f3f 100644 --- a/src/Symfony/Component/Stopwatch/StopwatchEvent.php +++ b/src/Symfony/Component/Stopwatch/StopwatchEvent.php @@ -33,6 +33,11 @@ class StopwatchEvent */ private $category; + /** + * @var bool + */ + private $morePrecision; + /** * @var float[] */ @@ -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; } /** @@ -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; } @@ -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; diff --git a/src/Symfony/Component/Stopwatch/StopwatchPeriod.php b/src/Symfony/Component/Stopwatch/StopwatchPeriod.php index 9876f179aadb6..c3ae266c9aecb 100644 --- a/src/Symfony/Component/Stopwatch/StopwatchPeriod.php +++ b/src/Symfony/Component/Stopwatch/StopwatchPeriod.php @@ -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() { @@ -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() { @@ -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() { diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchPeriodTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchPeriodTest.php new file mode 100644 index 0000000000000..f2387b8285bec --- /dev/null +++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchPeriodTest.php @@ -0,0 +1,67 @@ + + * + * 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); + } +}
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: