基准测试
CodeIgniter 提供两个独立的工具,用于基准测试代码并对比不同方案: Timer 和 Iterator。Timer 用于轻松计算脚本执行过程中任意两个时间点之间的耗时。Iterator 则支持设置多种代码变体并运行测试,通过记录性能和内存统计数据,辅助筛选最优版本。
Timer 类始终保持启用状态。该类从框架启动瞬间开始计时,直至向用户发送响应前结束,从而实现对整个系统执行过程的高精度计时。
使用 Timer
使用 Timer,可以测量应用执行过程中两个时刻之间的时间间隔。这样可以
轻松测量应用不同方面的性能。所有测量通过
start() 和 stop() 方法完成。
Timer::start()
start() 方法接受一个参数:计时器的名称。可以使用任意字符串作为
计时器名称。该名称仅用于后续引用,以便区分各个测量项:
<?php
$benchmark = service('timer');
$benchmark->start('render view');
Timer::stop()
stop() 方法接受要停止的计时器名称作为唯一参数:
<?php
$benchmark->stop('render view');
名称不区分大小写,但必须与启动计时器时使用的名称一致。
timer()
另外,也可以使用 全局函数 timer() 来启动
和停止计时器:
<?php
// Start the timer
timer('render view');
// Stop a running timer,
// if one of this name has been started
timer('render view');
Timer::record()
Added in version 4.3.0.
从 v4.3.0 开始,如果基准测试的代码块非常小,还可以使用 record() 方法。该方法接受
一个无参数的可调用对象并测量其执行时间。方法 start() 和 stop() 会在
函数调用前后自动执行。
<?php
$benchmark->record('slow_function', static function () { slow_function('...'); });
/*
* Same as:
*
* $benchmark->start('slow_function');
* slow_function('...');
* $benchmark->stop('slow_function');
*/
也可以返回可调用对象的返回值,以便进一步处理。
<?php
$length = $benchmark->record('string length', static fn () => strlen('CI4'));
/*
* $length = 3
*
* Same as:
*
* $benchmark->start('string length');
* $length = strlen('CI4');
* $benchmark->stop('string length');
*/
向 timer() 传递可调用对象作为第二个参数时,也提供相同的功能。
<?php
$length = timer('string length', static fn () => strlen('CI4'));
/*
* $length = 3
*
* Same as:
*
* timer('string length');
* $length = strlen('CI4');
* timer('string length');
*/
查看基准测试记录点
应用运行时,所有设置的计时器都会由 Timer 类收集。但
不会自动显示这些记录。可以通过调用 getTimers() 方法获取所有计时器。
该方法返回一个包含基准测试信息的数组,包括起始时间、结束时间和持续时间:
<?php
$timers = $benchmark->getTimers();
/*
* Produces:
* [
* 'render view' => [
* 'start' => 1234567890,
* 'end' => 1345678920,
* 'duration' => 15.4315, // number of seconds
* ]
* ]
*/
可以通过传递唯一参数来更改计算持续时间的精度,该参数指定要显示的小数位数。 默认值是小数点后 4 位:
<?php
$timers = $benchmark->getTimers(6);
计时器会自动显示在 Debug 工具栏 中。
显示执行时间
虽然 getTimers() 方法会提供项目中所有计时器的原始数据,但也可以获取
单个计时器的持续时间(秒),使用 getElapsedTime() 方法。第一个参数是要显示的
计时器名称。第二个参数是要显示的小数位数。默认值为 4:
<?php
echo timer()->getElapsedTime('render view');
// Displays: 0.0234
使用 Iterator
Iterator 是一个简单的工具,用于尝试多种解决方案的变体, 查看速度差异和不同的内存使用模式。可以添加任意数量的"任务"供 运行,该类会将任务运行数百或数千次,以更清晰地了解性能表现。 然后可以获取结果并在脚本中使用,或以 HTML 表格形式显示。
创建要运行的任务
任务在闭包中定义。任务产生的任何输出都会被自动丢弃。任务通过
add() 方法添加到 Iterator 类。第一个参数是用于引用
此测试的名称。第二个参数是闭包本身:
<?php
$iterator = new \CodeIgniter\Debug\Iterator();
$iterator->add('double', static function ($word = 'little') {
"Some basic {$word} string test.";
});
运行任务
添加要运行的任务后,可以使用 run() 方法循环执行任务多次。
默认情况下,每个任务运行 1000 次。对于大多数简单测试,这已经
足够。如果需要运行更多次数,可以将次数作为第一个参数传递:
<?php
// Run the tests 3000 times.
$htmlTable = $iterator->run(3000);
运行完成后,将返回包含测试结果的 HTML 表格。
如果不需要结果,可以将 false 作为第二个参数传递:
<?php
// Returns null.
$iterator->run(1000, false);