olivierperes/lambda-pi

向量的函数式接口的并行实现

dev-master 2016-11-14 16:19 UTC

This package is not auto-updated.

Last update: 2024-09-28 20:14:33 UTC


README

LambdaPi 是 PHP 中向量函数式(λ)接口的并行(π)实现。它提供了与 PHP 的 array_maparray_filterarray_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。