olivierperes / lambda-pi
向量的函数式接口的并行实现
Requires (Dev)
- phpunit/phpunit: 5.6.*
This package is not auto-updated.
Last update: 2024-09-28 20:14:33 UTC
README
LambdaPi 是 PHP 中向量函数式(λ)接口的并行(π)实现。它提供了与 PHP 的 array_map、array_filter 和 array_reduce 函数对应的实现,这些函数可以利用多核和多处理器系统。
此代码最初旨在作为演示,以展示在集合上采用函数式编程方法的好处。然而,它确实可以工作,并且应该可以在生产环境中使用。
基本示例
use OlivierPeres\LambdaPi\Vector; $values = [4, 8, 15, 16, 23, 42]; $vector = new Vector($values); echo $vector->map(function($x) { return $x*7; }) ->filter(function($x) { return $x % 2 == 0; }) ->reduce(function($x, $y) { return $x + $y; }, 0);
这创建了一个包含值 [4, 8, 15, 16, 23, 42] 的 Vector。然后,使用 map 方法创建一个新的 Vector,其中包含原始值乘以 7。之后,使用 filter 方法创建一个新的 Vector,其中只包含偶数。最后,使用 reduce 方法计算最后一个向量的元素总和。
当然,目的是在非常大的数组上执行这类计算。与常规 PHP 函数所需的时间相比,执行时间几乎减少了可用的处理器数量。 几乎 因为创建和管理进程以及进程间通信涉及到一定的开销。
方法
Vector 类提供了以下方法。
__construct(array $data)
: 构建一个包含给定数据的新 Vector。filter(callable $callback)
: 在 Vector 的每个元素上应用 $callback,并返回一个只包含 $callback 返回 true 的元素的新的 Vector。回调必须是一个纯函数,即它不能有任何副作用(如写入全局变量)。map(callable $callback)
: 在 Vector 的每个元素上应用 $callback,并返回一个包含结果的新的 Vector。回调必须是一个纯函数。reduce(callable $callback, $identity)
: 返回应用$callback($identity, ($callback(Vector[0], ... Vector[n])))
的结果。回调必须是一个纯函数,并且也必须是交换律和结合律的。身份值必须使得$callback($identity, $x) == $x
对任何$x
的值都成立。在空 Vector 上调用此方法返回身份值。
通过 Composer 安装
在您的 composer.json 中包含以下内容
"require": { "olivierperes/lambda-pi": "dev-master" }
如何运行单元测试
vendor/bin/phpunit
关于实现的几点说明
最初的计划是使用线程,但在 PHP 中这样做非常不切实际。它需要一个特别编译的 PHP 版本,这几乎不是提供软件包的通常来源提供的,还需要启用 pthreads 模块。
因此,LambdaPi 使用 pcntl_fork 创建完整的进程,这些进程通过 Unix 域套接字进行通信。多亏了这一点,没有依赖关系或先决条件,也没有任何配置要做。遗憾的是,这也意味着不支持 Windows。
当前的实现非常简单,当然可以优化。例如,可以使用进程池而不是每次都进行分叉。然而,这会很难做到,同时保持当前接口的简单性,因为使用进程池可能需要将回调限制为可序列化的值(即不是闭包)。请随意发送 PR。
目前,将要生成的进程数是硬编码在一个常量NB_CHILDREN中。将其增加以在具有更多核心的系统上测试LambdaPi。
许可
MIT。