基准测试

CodeIgniter 提供了两种独立的工具来帮助你基准测试代码和测试不同选项: TimerIterator。Timer 允许你轻松计算脚本执行过程中的两点之间的时间。Iterator 允许你设置几种变体并运行这些测试,记录性能和内存统计数据以帮助你决定哪种版本最佳。

Timer 类始终处于活动状态,从框架被调用的那一刻开始,直到向用户发送输出之前的最后一刻,使整个系统执行时间非常准确。

使用 Timer

通过 Timer,你可以测量应用程序执行过程中的两个时刻之间的时间。这使得测量应用程序不同方面的性能变得很简单。所有测量都使用 start()stop() 方法完成。

Timer::start()

start() 方法接受一个参数:计时器的名称。你可以使用任意字符串作为计时器的名称。它仅用于以后参考以知道哪个测量是哪个:

<?php

$benchmark = \Config\Services::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()

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 表格显示。

创建要运行的任务

任务在 Closure 中定义。任务创建的任何输出都将自动丢弃。它们通过 add() 方法添加到 Iterator 类中。第一个参数是你要引用此测试的名称。第二个参数是 Closure 本身:

<?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);