了解在何处使用 FFI
将 C 语言库直接导入 PHP 的潜力着实惊人。一位 PHP 核心开发人员就使用 FFI 扩展将 PHP 与 C 语言 TensorFlow 机器学习平台绑定!
有关 TensorFlow 机器学习平台的信息,请访问以下网页: https://www.tensorflow.org/ 。要了解如何将 PHP 与该库绑定,请点击此处: https://github.com/dstogov/php-tensorflow 。 |
正如我们在本节中向您介绍的那样,FFI 扩展并不是满足您所有需求的神奇解决方案。本节将讨论 FFI 扩展的主要优缺点,并提供使用指南。本节将揭穿一个神话,那就是使用 FFI 扩展直接调用 C 语言会加快 PHP 8 程序的执行速度。首先,让我们来看看将 FFI 扩展引入 PHP 花了多长时间。
在 PHP 中采用 FFI
第一个 FFI 扩展实际上是由 PHP 核心开发人员 Wez Furlong 和 Ilia Alshanetsky 于 2004 年 1 月在 PECL 网站 (https://pecl.php.net/) 上针对 PHP 5 推出的。然而,该项目从未通过 Alpha 阶段,在一个月内就放弃了开发。
在接下来的 14 年中,随着 PHP 的发展和成熟,PHP 显然将受益于直接在 PHP 脚本中快速创建潜在扩展原型的能力。如果没有这种能力,PHP 就有可能落后于 Python 和 Ruby 等其他语言。
过去,由于缺乏快速原型开发能力,扩展开发人员不得不编译完整的扩展并使用 pecl 进行安装,然后才能在 PHP 脚本中进行测试。在某些情况下,开发人员不得不重新编译 PHP 本身来测试他们的新扩展!相比之下,FFI 扩展允许开发人员直接将 C 函数调用放在 PHP 脚本中进行即时测试。
从 PHP 7.4 开始到 PHP 8,核心开发人员 Dmitry Stogov 提出了 FFI 扩展的改进版本。在经过令人信服的概念验证后(参见前面关于 PHP 与 TensorFlow 机器学习平台绑定的提示框),该 FFI 扩展版本被纳入了 PHP 语言。
原始 FFI PHP 扩展可以在这里找到: http://pecl.php.net/package/ffi 。有关修订后的 FFI 提案的更多信息,请参阅以下文章: https://wiki.php.net/rfc/ffi 。 |
现在让我们研究一下为什么不应该使用 FFI 来提高速度。
不要为了速度而使用 FFI
由于 FFI 扩展允许 PHP 直接访问 C 语言库,人们很容易相信 PHP 应用程序会突然以机器语言的速度快速运行。遗憾的是,事实并非如此。FFI 扩展需要首先打开给定的 C 库,然后在执行前解析和伪编译一个 FFI 实例。然后,FFI 扩展就充当了 C 库代码和 PHP 脚本之间的桥梁。
让一些读者感到欣慰的是,相对迟缓的 FFI 扩展性能并不局限于 PHP 8。其他语言在使用自己的 FFI 实现时也会受到同样的影响。这里有一个基于 Ary 3 基准的出色性能比较:https://wiki.php.net/rfc/ffi#php_ffi_ performance。
如果您查看一下刚才提到的网页上的表格,就会发现 Python FFI 实现执行基准测试的时间为 0.343 秒,而仅使用本地 Python 代码执行相同基准测试的时间为 0.212 秒。
查看同一张表,PHP 7.4 FFI 扩展执行基准测试的时间为 0.093 秒(比 Python 快 30 倍!),而仅使用本地 PHP 代码执行相同基准测试的时间为 0.040 秒。
下一个合乎逻辑的问题是:为什么要使用 FFI 扩展?下一节将讨论这个问题。
为什么使用 FFI 扩展?
前面问题的答案很简单:该扩展主要是为快速创建 PHP 扩展原型而设计的。PHP 扩展是该语言的生命线。没有扩展,PHP 只是另一种编程语言。
当高级开发人员第一次开始编程项目时,他们需要确定项目的最佳语言。其中一个关键因素是有多少可用的扩展以及这些扩展的维护积极性如何。一般来说,积极维护的扩展语言的数量与使用该语言的项目的长期成功潜力直接相关。
因此,如果有办法加快扩展开发,PHP 语言本身的长期生存能力就会得到提高。FFI 扩展为 PHP 语言带来的价值在于,它能够直接在 PHP 脚本中测试扩展原型,而无需经历编译-链接-加载-测试的整个周期。
在快速原型开发之外,FFI 扩展的另一个用例是允许 PHP 直接访问晦涩或专有的 C 代码。为控制工厂机器而编写的自定义 C 代码就是一个例子。为了让 PHP 运行工厂,可以使用 FFI 扩展将 PHP 与控制各种机器的 C 库直接绑定。
最后,该扩展的另一个用例是预加载 C 库,从而减少内存消耗。在展示使用示例之前,我们先来看看 FFI 类及其方法。