From bf7c6bc5736927e8060db99991a252493b2119a9 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 19:08:14 +0200 Subject: [PATCH 01/13] Add Timer method record for callables --- system/Common.php | 12 +++- system/Debug/Timer.php | 18 ++++++ tests/system/Debug/TimerTest.php | 95 ++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 3 deletions(-) diff --git a/system/Common.php b/system/Common.php index 962483bb68b2..6880a570664b 100644 --- a/system/Common.php +++ b/system/Common.php @@ -1076,12 +1076,14 @@ function stringify_attributes($attributes, bool $js = false): string if (! function_exists('timer')) { /** * A convenience method for working with the timer. - * If no parameter is passed, it will return the timer instance, - * otherwise will start or stop the timer intelligently. + * If no parameter is passed, it will return the timer instance. + * If callable is passed, it measures time of callable and + * returns its return value if any. + * Otherwise will start or stop the timer intelligently. * * @return mixed|Timer */ - function timer(?string $name = null) + function timer(?string $name = null, ?callable $callable) { $timer = Services::timer(); @@ -1089,6 +1091,10 @@ function timer(?string $name = null) return $timer; } + if (! is_null($callable)) { + return $timer->record($name, $callable); + } + if ($timer->has($name)) { return $timer->stop($name); } diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 9ca51d1c9b08..a576eb9586e4 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -126,4 +126,22 @@ public function has(string $name): bool { return array_key_exists(strtolower($name), $this->timers); } + + /** + * Executes callable and measures its time. + * Returns its return value if any. + * + * @param string $name The name of the timer + * @param callable $callable callable to be executed + * + * @return mixed|null + */ + public function record(string $name, callable $callable) + { + $this->start($name); + $returnValue = call_user_func($callable); + $this->stop($name); + + return $returnValue; + } } diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index fdd09829d9ff..f3ca047bf4b9 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -121,4 +121,99 @@ public function testReturnsNullGettingElapsedTimeOfNonTimer() $this->assertNull($timer->getElapsedTime('test1')); } + + /** + * @timeLimit 1.5 + */ + public function testRecordFunctionNoReturn() + { + $timer = new Timer(); + $returnValue = $timer->record('longjohn', function() { sleep(1); }); + + $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertNull($returnValue); + } + + /** + * @timeLimit 1.5 + */ + public function testRecordFunctionWithReturn() + { + $timer = new Timer(); + $returnValue = $timer->record('longjohn', function() { sleep(1); return 'test'; }); + + $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertSame('test', $returnValue); + } + + public function testRecordArrowFunction() + { + $timer = new Timer(); + $returnValue = $timer->record('longjohn', fn() => strlen('CI4') ); + + $this->assertLessThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertSame(3, $returnValue); + } + + public function testRecordThrowsException() + { + $this->expectException('RuntimeException'); + + $timer = new Timer(); + $timer->record('ex', function() { throw new RuntimeException(); }); + } + + public function testRecordThrowsErrorOnCallableWithParams() + { + $this->expectException('Error'); + + $timer = new Timer(); + $timer->record('error', 'strlen'); + } + + public function testCommonNoNameExpectTimer() + { + $returnValue = timer(); + + $this->assertInstanceOf(Timer::class, $returnValue); + } + + public function testCommonWithNameExpectTimer() + { + $returnValue = timer('test'); + + $this->assertInstanceOf(Timer::class, $returnValue); + $this->assertTrue($returnValue->has('test')); + } + + public function testCommonNoNameCallableExpectTimer() + { + $returnValue = timer(null, fn() => strlen('CI4') ); + + $this->assertInstanceOf(Timer::class, $returnValue); + } + + /** + * @timeLimit 1.5 + */ + public function testCommonCallableExpectNoReturn() + { + $returnValue = timer('common', function() { sleep(1); } ); + + $this->assertNotInstanceOf(Timer::class, $returnValue); + $this->assertNull($returnValue); + $this->assertGreaterThanOrEqual(1.0, timer()->getElapsedTime('common')); + } + + /** + * @timeLimit 1.5 + */ + public function testCommonCallableExpectWithReturn() + { + $returnValue = timer('common', function() { sleep(1); return strlen('CI4'); } ); + + $this->assertNotInstanceOf(Timer::class, $returnValue); + $this->assertSame(3, $returnValue); + $this->assertGreaterThanOrEqual(1.0, timer()->getElapsedTime('common')); + } } From ba1cc5cdf0ce507d99a34f06b2159fe83d414973 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 19:16:56 +0200 Subject: [PATCH 02/13] Code fixes --- system/Common.php | 2 +- tests/system/Debug/TimerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Common.php b/system/Common.php index 6880a570664b..8af9122e846f 100644 --- a/system/Common.php +++ b/system/Common.php @@ -1083,7 +1083,7 @@ function stringify_attributes($attributes, bool $js = false): string * * @return mixed|Timer */ - function timer(?string $name = null, ?callable $callable) + function timer(?string $name = null, ?callable $callable = null) { $timer = Services::timer(); diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index f3ca047bf4b9..402348797a6c 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -160,7 +160,7 @@ public function testRecordThrowsException() $this->expectException('RuntimeException'); $timer = new Timer(); - $timer->record('ex', function() { throw new RuntimeException(); }); + $timer->record('ex', function() { throw new \RuntimeException(); }); } public function testRecordThrowsErrorOnCallableWithParams() From 22194d0620ec05c4d599fd79420a8d102fa3ea45 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 19:19:01 +0200 Subject: [PATCH 03/13] Changelogs and user guide --- user_guide_src/source/changelogs/v4.3.0.rst | 1 + user_guide_src/source/testing/benchmark.rst | 14 ++++++++++++++ user_guide_src/source/testing/benchmark/010.php | 11 +++++++++++ user_guide_src/source/testing/benchmark/011.php | 13 +++++++++++++ user_guide_src/source/testing/benchmark/012.php | 13 +++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 user_guide_src/source/testing/benchmark/010.php create mode 100644 user_guide_src/source/testing/benchmark/011.php create mode 100644 user_guide_src/source/testing/benchmark/012.php diff --git a/user_guide_src/source/changelogs/v4.3.0.rst b/user_guide_src/source/changelogs/v4.3.0.rst index 9c62bb05c150..2f250c389f38 100644 --- a/user_guide_src/source/changelogs/v4.3.0.rst +++ b/user_guide_src/source/changelogs/v4.3.0.rst @@ -41,6 +41,7 @@ Enhancements - SQLite ``BaseConnection::getIndexData()`` now can return pseudo index named ``PRIMARY`` for `AUTOINCREMENT` column, and each returned index data has ``type`` property. - Added ``spark filter:check`` command to check the filters for a route. See :ref:`Controller Filters ` for the details. - Now **Encryption** can decrypt data encrypted with CI3's Encryption. See :ref:`encryption-compatible-with-ci3`. +- Added method ``Timer::record`` to measure performance in a callable. Also enhanced common function ``timer()`` to accept optional callable. Changes ******* diff --git a/user_guide_src/source/testing/benchmark.rst b/user_guide_src/source/testing/benchmark.rst index fb92eb19dfec..072021a2afb3 100644 --- a/user_guide_src/source/testing/benchmark.rst +++ b/user_guide_src/source/testing/benchmark.rst @@ -38,6 +38,20 @@ and stop timers: .. literalinclude:: benchmark/003.php +If you use very small code blocks to benchmark, you can also use the ``record()`` method. It accepts +a no-parameter callable and measures its execution time. Methods ``start()`` and ``stop()`` will be called +automatically around the function call. + +.. literalinclude:: benchmark/010.php + +You can also return the callable's return value for further processing. + +.. literalinclude:: benchmark/011.php + +The same functionality is also available when passing callable to ``timer()`` as second parameter. + +.. literalinclude:: benchmark/012.php + Viewing Your Benchmark Points ============================= diff --git a/user_guide_src/source/testing/benchmark/010.php b/user_guide_src/source/testing/benchmark/010.php new file mode 100644 index 000000000000..ae958b1c1471 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/010.php @@ -0,0 +1,11 @@ +record('slow_function', function() { slow_function('...'); }); + +/* + * Same as: + * + * $benchmark->start('slow_function'); + * slow_function('...'); + * $benchmark->stop('slow_function'); +*/ \ No newline at end of file diff --git a/user_guide_src/source/testing/benchmark/011.php b/user_guide_src/source/testing/benchmark/011.php new file mode 100644 index 000000000000..5e09cd4d98b5 --- /dev/null +++ b/user_guide_src/source/testing/benchmark/011.php @@ -0,0 +1,13 @@ +record('string length', fn() => strlen('CI4') ); + +/* + * $length = 3 + * + * Same as: + * + * $benchmark->start('string length'); + * $length = strlen('CI4'); + * $benchmark->stop('string length'); +*/ \ No newline at end of file diff --git a/user_guide_src/source/testing/benchmark/012.php b/user_guide_src/source/testing/benchmark/012.php new file mode 100644 index 000000000000..b4b942ab3d6d --- /dev/null +++ b/user_guide_src/source/testing/benchmark/012.php @@ -0,0 +1,13 @@ + strlen('CI4') ); + +/* + * $length = 3 + * + * Same as: + * + * timer('string length'); + * $length = strlen('CI4'); + * timer('string length'); +*/ \ No newline at end of file From 3dbcc7fdc5a81953fc5655333f5c25b4c1f77126 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 19:27:06 +0200 Subject: [PATCH 04/13] CS-Fixer changes --- system/Common.php | 2 +- system/Debug/Timer.php | 10 +++++----- tests/system/Debug/TimerTest.php | 25 +++++++++++++++---------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/system/Common.php b/system/Common.php index 8af9122e846f..2215da3f7679 100644 --- a/system/Common.php +++ b/system/Common.php @@ -1091,7 +1091,7 @@ function timer(?string $name = null, ?callable $callable = null) return $timer; } - if (! is_null($callable)) { + if (null !== $callable) { return $timer->record($name, $callable); } diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index a576eb9586e4..1e34a708e98a 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -130,16 +130,16 @@ public function has(string $name): bool /** * Executes callable and measures its time. * Returns its return value if any. - * - * @param string $name The name of the timer - * @param callable $callable callable to be executed - * + * + * @param string $name The name of the timer + * @param callable $callable callable to be executed + * * @return mixed|null */ public function record(string $name, callable $callable) { $this->start($name); - $returnValue = call_user_func($callable); + $returnValue = $callable(); $this->stop($name); return $returnValue; diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 402348797a6c..5e0ffbd5c7b2 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Debug; use CodeIgniter\Test\CIUnitTestCase; +use RuntimeException; /** * @internal @@ -127,8 +128,8 @@ public function testReturnsNullGettingElapsedTimeOfNonTimer() */ public function testRecordFunctionNoReturn() { - $timer = new Timer(); - $returnValue = $timer->record('longjohn', function() { sleep(1); }); + $timer = new Timer(); + $returnValue = $timer->record('longjohn', static function () { sleep(1); }); $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); $this->assertNull($returnValue); @@ -139,8 +140,10 @@ public function testRecordFunctionNoReturn() */ public function testRecordFunctionWithReturn() { - $timer = new Timer(); - $returnValue = $timer->record('longjohn', function() { sleep(1); return 'test'; }); + $timer = new Timer(); + $returnValue = $timer->record('longjohn', static function () { sleep(1); + +return 'test'; }); $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); $this->assertSame('test', $returnValue); @@ -148,8 +151,8 @@ public function testRecordFunctionWithReturn() public function testRecordArrowFunction() { - $timer = new Timer(); - $returnValue = $timer->record('longjohn', fn() => strlen('CI4') ); + $timer = new Timer(); + $returnValue = $timer->record('longjohn', static fn () => strlen('CI4')); $this->assertLessThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); $this->assertSame(3, $returnValue); @@ -160,7 +163,7 @@ public function testRecordThrowsException() $this->expectException('RuntimeException'); $timer = new Timer(); - $timer->record('ex', function() { throw new \RuntimeException(); }); + $timer->record('ex', static function () { throw new RuntimeException(); }); } public function testRecordThrowsErrorOnCallableWithParams() @@ -188,7 +191,7 @@ public function testCommonWithNameExpectTimer() public function testCommonNoNameCallableExpectTimer() { - $returnValue = timer(null, fn() => strlen('CI4') ); + $returnValue = timer(null, static fn () => strlen('CI4')); $this->assertInstanceOf(Timer::class, $returnValue); } @@ -198,7 +201,7 @@ public function testCommonNoNameCallableExpectTimer() */ public function testCommonCallableExpectNoReturn() { - $returnValue = timer('common', function() { sleep(1); } ); + $returnValue = timer('common', static function () { sleep(1); }); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertNull($returnValue); @@ -210,7 +213,9 @@ public function testCommonCallableExpectNoReturn() */ public function testCommonCallableExpectWithReturn() { - $returnValue = timer('common', function() { sleep(1); return strlen('CI4'); } ); + $returnValue = timer('common', static function () { sleep(1); + +return strlen('CI4'); }); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertSame(3, $returnValue); From 838995bd9ffc86b10c3d7f164b1632ec44dedfed Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 19:48:52 +0200 Subject: [PATCH 05/13] Fixed CS-Fixer style issues --- tests/system/Debug/TimerTest.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 5e0ffbd5c7b2..62ed83b74fb3 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -141,9 +141,10 @@ public function testRecordFunctionNoReturn() public function testRecordFunctionWithReturn() { $timer = new Timer(); - $returnValue = $timer->record('longjohn', static function () { sleep(1); - -return 'test'; }); + $returnValue = $timer->record('longjohn', static function () { + sleep(1); + return 'test'; + }); $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); $this->assertSame('test', $returnValue); @@ -213,9 +214,10 @@ public function testCommonCallableExpectNoReturn() */ public function testCommonCallableExpectWithReturn() { - $returnValue = timer('common', static function () { sleep(1); - -return strlen('CI4'); }); + $returnValue = timer('common', static function () { + sleep(1); + return strlen('CI4'); + }); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertSame(3, $returnValue); From a47411b01626dd9bbf6ade87fa6189dbfecceafe Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 20:21:23 +0200 Subject: [PATCH 06/13] Unit test fixes for v7, added more new lines --- tests/system/Debug/TimerTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 62ed83b74fb3..d6a1cbe3b5e9 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -143,6 +143,7 @@ public function testRecordFunctionWithReturn() $timer = new Timer(); $returnValue = $timer->record('longjohn', static function () { sleep(1); + return 'test'; }); @@ -169,7 +170,7 @@ public function testRecordThrowsException() public function testRecordThrowsErrorOnCallableWithParams() { - $this->expectException('Error'); + $this->expectException('Throwable'); $timer = new Timer(); $timer->record('error', 'strlen'); @@ -216,6 +217,7 @@ public function testCommonCallableExpectWithReturn() { $returnValue = timer('common', static function () { sleep(1); + return strlen('CI4'); }); From 9603cea4f9c7909f1f41afdc192a95653340701e Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Sun, 31 Jul 2022 21:21:32 +0200 Subject: [PATCH 07/13] Further CS-Fixer changes --- tests/system/Debug/TimerTest.php | 5 +++-- user_guide_src/source/testing/benchmark/010.php | 4 ++-- user_guide_src/source/testing/benchmark/011.php | 6 +++--- user_guide_src/source/testing/benchmark/012.php | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index d6a1cbe3b5e9..580432b0ee96 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -13,6 +13,7 @@ use CodeIgniter\Test\CIUnitTestCase; use RuntimeException; +use Throwable; /** * @internal @@ -162,7 +163,7 @@ public function testRecordArrowFunction() public function testRecordThrowsException() { - $this->expectException('RuntimeException'); + $this->expectException(RuntimeException::class); $timer = new Timer(); $timer->record('ex', static function () { throw new RuntimeException(); }); @@ -170,7 +171,7 @@ public function testRecordThrowsException() public function testRecordThrowsErrorOnCallableWithParams() { - $this->expectException('Throwable'); + $this->expectException(Throwable::class); $timer = new Timer(); $timer->record('error', 'strlen'); diff --git a/user_guide_src/source/testing/benchmark/010.php b/user_guide_src/source/testing/benchmark/010.php index ae958b1c1471..76a5405b7129 100644 --- a/user_guide_src/source/testing/benchmark/010.php +++ b/user_guide_src/source/testing/benchmark/010.php @@ -1,10 +1,10 @@ record('slow_function', function() { slow_function('...'); }); +$benchmark->record('slow_function', static function () { slow_function('...'); }); /* * Same as: - * + * * $benchmark->start('slow_function'); * slow_function('...'); * $benchmark->stop('slow_function'); diff --git a/user_guide_src/source/testing/benchmark/011.php b/user_guide_src/source/testing/benchmark/011.php index 5e09cd4d98b5..bc12efafa3a4 100644 --- a/user_guide_src/source/testing/benchmark/011.php +++ b/user_guide_src/source/testing/benchmark/011.php @@ -1,12 +1,12 @@ record('string length', fn() => strlen('CI4') ); +$length = $benchmark->record('string length', static fn () => strlen('CI4')); /* * $length = 3 - * + * * Same as: - * + * * $benchmark->start('string length'); * $length = strlen('CI4'); * $benchmark->stop('string length'); diff --git a/user_guide_src/source/testing/benchmark/012.php b/user_guide_src/source/testing/benchmark/012.php index b4b942ab3d6d..2a964324df88 100644 --- a/user_guide_src/source/testing/benchmark/012.php +++ b/user_guide_src/source/testing/benchmark/012.php @@ -1,12 +1,12 @@ strlen('CI4') ); +$length = timer('string length', static fn () => strlen('CI4')); /* * $length = 3 - * + * * Same as: - * + * * timer('string length'); * $length = strlen('CI4'); * timer('string length'); From 66d271ccec70467ca390c150101779234ab2c8b3 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Mon, 1 Aug 2022 18:58:57 +0200 Subject: [PATCH 08/13] Changes according to Reviews --- system/Common.php | 2 +- system/Debug/Timer.php | 2 +- user_guide_src/source/testing/benchmark/010.php | 2 +- user_guide_src/source/testing/benchmark/011.php | 2 +- user_guide_src/source/testing/benchmark/012.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/system/Common.php b/system/Common.php index 2215da3f7679..4e3a67e62dff 100644 --- a/system/Common.php +++ b/system/Common.php @@ -1091,7 +1091,7 @@ function timer(?string $name = null, ?callable $callable = null) return $timer; } - if (null !== $callable) { + if ($callable !== null) { return $timer->record($name, $callable); } diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 1e34a708e98a..98bd9e574a24 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -134,7 +134,7 @@ public function has(string $name): bool * @param string $name The name of the timer * @param callable $callable callable to be executed * - * @return mixed|null + * @return object|resource|array|string|int|float|bool|null */ public function record(string $name, callable $callable) { diff --git a/user_guide_src/source/testing/benchmark/010.php b/user_guide_src/source/testing/benchmark/010.php index 76a5405b7129..e148c83f6fbe 100644 --- a/user_guide_src/source/testing/benchmark/010.php +++ b/user_guide_src/source/testing/benchmark/010.php @@ -8,4 +8,4 @@ * $benchmark->start('slow_function'); * slow_function('...'); * $benchmark->stop('slow_function'); -*/ \ No newline at end of file +*/ diff --git a/user_guide_src/source/testing/benchmark/011.php b/user_guide_src/source/testing/benchmark/011.php index bc12efafa3a4..239d193a5ca8 100644 --- a/user_guide_src/source/testing/benchmark/011.php +++ b/user_guide_src/source/testing/benchmark/011.php @@ -10,4 +10,4 @@ * $benchmark->start('string length'); * $length = strlen('CI4'); * $benchmark->stop('string length'); -*/ \ No newline at end of file +*/ diff --git a/user_guide_src/source/testing/benchmark/012.php b/user_guide_src/source/testing/benchmark/012.php index 2a964324df88..ecd25688b556 100644 --- a/user_guide_src/source/testing/benchmark/012.php +++ b/user_guide_src/source/testing/benchmark/012.php @@ -10,4 +10,4 @@ * timer('string length'); * $length = strlen('CI4'); * timer('string length'); -*/ \ No newline at end of file +*/ From be61a5da4587d379bd185b941b1433bf66b5645e Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Tue, 2 Aug 2022 09:54:52 +0200 Subject: [PATCH 09/13] Improved unit tests, style and docu --- system/Debug/Timer.php | 2 +- tests/system/Debug/TimerTest.php | 21 +++++---------------- user_guide_src/source/testing/benchmark.rst | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 98bd9e574a24..27b9a6a7c1f7 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -134,7 +134,7 @@ public function has(string $name): bool * @param string $name The name of the timer * @param callable $callable callable to be executed * - * @return object|resource|array|string|int|float|bool|null + * @return array|bool|float|int|object|resource|string|null */ public function record(string $name, callable $callable) { diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 580432b0ee96..16e9eda9d7e4 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -11,6 +11,7 @@ namespace CodeIgniter\Debug; +use ArgumentCountError; use CodeIgniter\Test\CIUnitTestCase; use RuntimeException; use Throwable; @@ -136,19 +137,14 @@ public function testRecordFunctionNoReturn() $this->assertNull($returnValue); } - /** - * @timeLimit 1.5 - */ public function testRecordFunctionWithReturn() { $timer = new Timer(); $returnValue = $timer->record('longjohn', static function () { - sleep(1); - return 'test'; }); - $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertLessThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); $this->assertSame('test', $returnValue); } @@ -171,7 +167,7 @@ public function testRecordThrowsException() public function testRecordThrowsErrorOnCallableWithParams() { - $this->expectException(Throwable::class); + $this->expectException(ArgumentCountError::class); $timer = new Timer(); $timer->record('error', 'strlen'); @@ -211,19 +207,12 @@ public function testCommonCallableExpectNoReturn() $this->assertGreaterThanOrEqual(1.0, timer()->getElapsedTime('common')); } - /** - * @timeLimit 1.5 - */ public function testCommonCallableExpectWithReturn() { - $returnValue = timer('common', static function () { - sleep(1); - - return strlen('CI4'); - }); + $returnValue = timer('common', static fn () => strlen('CI4')); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertSame(3, $returnValue); - $this->assertGreaterThanOrEqual(1.0, timer()->getElapsedTime('common')); + $this->assertLessThanOrEqual(1.0, timer()->getElapsedTime('common')); } } diff --git a/user_guide_src/source/testing/benchmark.rst b/user_guide_src/source/testing/benchmark.rst index 072021a2afb3..68429df4aebe 100644 --- a/user_guide_src/source/testing/benchmark.rst +++ b/user_guide_src/source/testing/benchmark.rst @@ -38,7 +38,7 @@ and stop timers: .. literalinclude:: benchmark/003.php -If you use very small code blocks to benchmark, you can also use the ``record()`` method. It accepts +Since v4.3.0, if you use very small code blocks to benchmark, you can also use the ``record()`` method. It accepts a no-parameter callable and measures its execution time. Methods ``start()`` and ``stop()`` will be called automatically around the function call. From b5d5591e2e75c7ed79221431e3c23a0260f639db Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Tue, 2 Aug 2022 20:24:53 +0200 Subject: [PATCH 10/13] reduced sleep time in unit tests --- tests/system/Debug/TimerTest.php | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 16e9eda9d7e4..9d8d9a93c2b6 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -14,7 +14,6 @@ use ArgumentCountError; use CodeIgniter\Test\CIUnitTestCase; use RuntimeException; -use Throwable; /** * @internal @@ -125,15 +124,12 @@ public function testReturnsNullGettingElapsedTimeOfNonTimer() $this->assertNull($timer->getElapsedTime('test1')); } - /** - * @timeLimit 1.5 - */ public function testRecordFunctionNoReturn() { $timer = new Timer(); - $returnValue = $timer->record('longjohn', static function () { sleep(1); }); + $returnValue = $timer->record('longjohn', static function () { usleep(100000); }); - $this->assertGreaterThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertGreaterThanOrEqual(0.1, $timer->getElapsedTime('longjohn')); $this->assertNull($returnValue); } @@ -141,10 +137,12 @@ public function testRecordFunctionWithReturn() { $timer = new Timer(); $returnValue = $timer->record('longjohn', static function () { + usleep(100000); + return 'test'; }); - $this->assertLessThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertGreaterThanOrEqual(0.1, $timer->getElapsedTime('longjohn')); $this->assertSame('test', $returnValue); } @@ -195,16 +193,13 @@ public function testCommonNoNameCallableExpectTimer() $this->assertInstanceOf(Timer::class, $returnValue); } - /** - * @timeLimit 1.5 - */ public function testCommonCallableExpectNoReturn() { - $returnValue = timer('common', static function () { sleep(1); }); + $returnValue = timer('common', static function () { usleep(100000); }); $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertNull($returnValue); - $this->assertGreaterThanOrEqual(1.0, timer()->getElapsedTime('common')); + $this->assertGreaterThanOrEqual(0.1, timer()->getElapsedTime('common')); } public function testCommonCallableExpectWithReturn() @@ -213,6 +208,6 @@ public function testCommonCallableExpectWithReturn() $this->assertNotInstanceOf(Timer::class, $returnValue); $this->assertSame(3, $returnValue); - $this->assertLessThanOrEqual(1.0, timer()->getElapsedTime('common')); + $this->assertLessThanOrEqual(0.1, timer()->getElapsedTime('common')); } } From 5512618e3fe73e4dcc91cbc6c0570a0d3f8740c7 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Wed, 3 Aug 2022 20:02:39 +0200 Subject: [PATCH 11/13] Removed whitespaces in blank line --- tests/system/Debug/TimerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 9d8d9a93c2b6..c7b9a2554241 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -138,7 +138,7 @@ public function testRecordFunctionWithReturn() $timer = new Timer(); $returnValue = $timer->record('longjohn', static function () { usleep(100000); - + return 'test'; }); From 9a0ad2660041fac6a0580a1d78bba01b3b730041 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Thu, 4 Aug 2022 13:40:40 +0200 Subject: [PATCH 12/13] PHP version specific test --- tests/system/Debug/TimerTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index c7b9a2554241..21e802b17fce 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -13,6 +13,7 @@ use ArgumentCountError; use CodeIgniter\Test\CIUnitTestCase; +use ErrorException; use RuntimeException; /** @@ -151,7 +152,7 @@ public function testRecordArrowFunction() $timer = new Timer(); $returnValue = $timer->record('longjohn', static fn () => strlen('CI4')); - $this->assertLessThanOrEqual(1.0, $timer->getElapsedTime('longjohn')); + $this->assertLessThan(0.1, $timer->getElapsedTime('longjohn')); $this->assertSame(3, $returnValue); } @@ -165,7 +166,11 @@ public function testRecordThrowsException() public function testRecordThrowsErrorOnCallableWithParams() { - $this->expectException(ArgumentCountError::class); + if(version_compare(PHP_VERSION, '8.0.0') >= 0) { + $this->expectException(ArgumentCountError::class); + } else { + $this->expectException(ErrorException::class); + } $timer = new Timer(); $timer->record('error', 'strlen'); From 4a122f3d53ec756eaf1cf5217be52fcc03a2e5b4 Mon Sep 17 00:00:00 2001 From: Christian Rumpf Date: Thu, 4 Aug 2022 14:00:02 +0200 Subject: [PATCH 13/13] Fixed CS --- tests/system/Debug/TimerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 21e802b17fce..bdbe31aeb759 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -166,7 +166,7 @@ public function testRecordThrowsException() public function testRecordThrowsErrorOnCallableWithParams() { - if(version_compare(PHP_VERSION, '8.0.0') >= 0) { + if (version_compare(PHP_VERSION, '8.0.0') >= 0) { $this->expectException(ArgumentCountError::class); } else { $this->expectException(ErrorException::class);