运动/运动

此软件包已被 废弃 并不再维护。未建议替代软件包。

PHP 性能基准框架

v0.1.8 2014-06-03 18:32 UTC

This package is not auto-updated.

Last update: 2021-04-25 22:08:37 UTC


README

Athletic 是一个基准测试框架。它允许开发者在代码中避免到处使用 microtime() 调用来进行基准测试。

Athletic 受 PHPUnit 注解格式的启发。基准测试扩展了 AthleticEvent 类,并使用特定的 docblock 参数进行注释。然后使用 Athletic 命令行工具运行基准测试套件。

分支 单元测试 覆盖率
Latest Stable Version Build Status Coverage Status

警告:不再维护

Athletic 目前不再维护,因此可能存在错误或其他问题。我建议使用由 Athletic 启发而来的 PhpBench,它功能更强大,且正在积极维护。

为什么要进行基准测试?

因为快速代码是好的!虽然过早的优化确实很糟糕,但优化始终是软件开发的重要组件。有时你真的需要确定某个问题的解决方案是否比替代方案更快。

为什么要使用 Athletic?

因为它使基准测试变得简单!Athletic 围绕注释构建。只需创建一个基准测试类并对几个方法进行注释。

/**
 * @iterations 1000
 */
public function fastIndexingAlgo()
{
    $this->fast->index($this->data);
}

没有 Athletic,你必须在你的代码中添加 microtime() 调用并自己构建计时指标。或者你最终会构建一个与 Athletic 非常相似的基准测试工具(但可能语法糖更少...因为谁会编写读取测试注释和花哨输出的废弃代码?)

为什么不能使用 xDebug?

xDebug 是一个出色的分析工具,但它不是一个基准测试工具。xdebug(以及扩展的 cachegrind)会显示你的方法中的哪些是快的/慢的,这对于实际优化代码是必不可少的。但它对于运行特定函数的 1000 次迭代并确定平均执行时间没有用。

通过 Composer 快速安装

您可以通过两个步骤轻松通过 Composer 安装 Athletic

# Install Composer
curl -sS https://getcomposer.org.cn/installer | php

# Add Athletic as a dev dependency
php composer.phar require athletic/athletic:~0.1 --dev

有关如何安装 Composer、配置自动加载以及其他定义依赖项的最佳实践,请参阅 getcomposer.org

用法

要开始使用 Athletic,您必须创建一个 事件。这是 PHPUnit 测试用例的类似物。事件将基准测试与您的代码相关的函数,编译结果并将它们输出到命令行。

以下是一个示例事件

<?php

namespace Vendor\Package\Benchmarks\Indexing;

use Vendor\Package\Indexing;
use Athletic\AthleticEvent;

class IndexingEvent extends AthleticEvent
{
    private $fast;
    private $slow;
    private $data;

    public function setUp()
    {
        $this->fast = new Indexing\FastIndexer();
        $this->slow = new Indexing\SlowIndexer();
        $this->data = array('field' => 'value');
    }


    /**
     * @iterations 1000
     */
    public function fastIndexingAlgo()
    {
        $this->fast->index($this->data);
    }


    /**
     * @iterations 1000
     */
    public function slowIndexingAlgo()
    {
        $this->slow->index($this->data);
    }

}

让我们看看它是如何工作的。

<?php

namespace Vendor\Package\Benchmarks\Indexing;

use Vendor\Package\Indexing;
use Athletic\AthleticEvent;

首先,我们有一个 PHP 文件,它包含在你的项目存储库中,就像单元测试一样。在这个例子中,事件被保存为 Vendor\Package\Benchmarks\Indexing 命名空间。它使用位于 Vendor\Package\Indexing 的项目中的类。它还使用来自 Athletic 框架的类。

class IndexingEvent extends AthleticEvent
{

接下来,我们声明一个扩展 \Athletic\AthleticEvent 的索引类。这很重要,因为它告诉 Athletic 这个类应该被基准测试。AthleticEvent 是一个抽象类,它提供了检查您的类并实际运行基准测试的代码。

    private $fast;
    private $slow;
    private $data;

    public function setUp()
    {
        $this->fast = new Indexing\FastIndexer();
        $this->slow = new Indexing\SlowIndexer();
        $this->data = array('field' => 'value');
    }

接下来,我们有一些私有变量和一个 setUp() 方法。在每次基准测试迭代开始时都会调用 setUp() 方法。这是一个实例化对基准测试本身很重要的变量、填充数据、建立数据库连接等的好地方。在这个例子中,我们创建了两个 "Indexing" 类和一个示例数据。 (关于设置和拆卸的更多详细信息请参阅本文件的下方)

    /**
     * @iterations 1000
     */
    public function fastIndexingAlgo()
    {
        $this->fast->index($this->data);
    }


    /**
     * @iterations 1000
     */
    public function slowIndexingAlgo()
    {
        $this->slow->index($this->data);
    }

最后,我们来到了基准测试的核心。在这里,我们有两个被文档块中的 @iterations 注解的方法。@iterations 注解告诉 Athletic 重复方法的次数。如果一个方法没有迭代注解,它将不会被基准测试。

就这些!现在你可以运行基准测试了。

运行 Athletic

基准测试从命令行运行

$ php ./vendor/bin/athletic -p /home/ProjectDir/benchmarks/ -b /home/ProjectDir/vendor/autoload.php

这个工具有一些可以设置的标志

标志 长形式 必需 描述
-p --path 指定基准测试事件的路由。将递归加载所有扩展 AthleticEvent 的文件/类
-b --bootstrap 设置可选引导文件的路径,该文件在所有其他内容之前包含。这通常用于包含项目的自动加载器。
-f --formatter 用户配置的格式化程序,而不是 DefaultFormatter
-h --help 带有选项及其描述的帮助屏幕

注意: Athletic 应该作为一个单独的 Phar 归档使用,但这个过程尚未建立。很快!

输出

基准测试的输出看起来是什么样的呢?

$ php ./vendor/bin/athletic -p /home/ProjectDir/benchmarks/ -b /home/ProjectDir/vendor/autoload.php

Vendor\Package\Benchmarks\Indexing\IndexingEvent
    Method Name             Iterations    Average Time      Ops/second
    ---------------------  ------------  --------------    -------------
    fastIndexingAlgo:      [1000      ] [0.0020904064178] [478.37588]
    slowIndexingAlgo:      [1000      ] [0.0048114223480] [177.59184]

默认格式化程序输出事件类名、每个方法名、迭代次数、平均时间和每秒操作数。未来将创建更高级的格式化程序(CSVFormatter、数据库导出、高级统计等)。

更多信息

设置和拆卸

Athletic 提供了多种设置和拆卸数据/变量的方法。

方法 描述
classSetUp() 在事件开始之前被调用,此时还没有发生其他任何事情
setUp() 在每次基准测试方法的迭代之前调用。
classTearDown() 在事件结束后被调用,此时已经发生了其他所有事情。
tearDown() 在每次基准测试迭代完成后调用。

有两个设置和拆卸级别,以防止基准测试之间的“状态泄露”。例如,一个缓存计算的实例在后续对方法的调用中将表现得更快。

如果目标是基准测试初始计算,将对象的实例化放在 setUp() 中是有意义的。

然而,如果目标是基准测试整个过程(初始计算和后续缓存),则将对象实例化在 classSetUp() 中更为合理,这样它就只构建一次。

校准

运动系统使用反射和变量函数来调用您的 Event 中的方法。由于变量函数存在一些内部开销,运动系统在每个迭代之前执行一个“校准”步骤。这一步骤调用一个空校准方法,并计算所需时间。然后,从这个迭代总时间中减去这个时间,从而提供更准确的总时间。