在 mizu 框架中,一次任务往返耗时不到一微秒,这比标准 Python 进程池典型的约 100 µs 开销提高了两个数量级。这一性能飞跃允许开发者像使用线程一样精细地分配工作,使得即使是极小的 10 微秒任务也能进行并行执行。

,

克服序列化瓶颈

Python 和 R 中的标准进程池通常会遭受巨大的开销,因为每个任务都必须经过序列化、通过套接字复制,然后由工作进程进行反序列化。当任务较小时,这种通信成本可能超过实际的计算时间;而大型数据集可能会因在不同进程中创建多个副本而耗尽内存。

Mizu 通过使用名为 libmizu 的 C 库来促进无锁共享内存进程间通信(IPC)来解决此问题。任务不是被复制,而是仅被写入到两个进程都能看到的内存中,允许工作进程直接读取数据而无需额外开销。

— GitHub - shikokuchuo/pymizu: Thread-speed async and parallel Python over shared memory

> “任务往返时间从通过套接字的约 100 µs 降至 1 µs 以下,因此你可以像使用线程一样精细地划分工作”

架构与性能提升

该架构利用带有批量发布和“自旋后挂起”等待机制的无锁单生产者单消费者环。这种设计确保系统在热路径上不进入内核,仅在对等进程死亡时触发操作系统通知。

在 Apple M4 Pro 上的基准测试显示,与 ProcessPoolExecutor 相比,pymizu 在单个工作进程的流水线吞吐量上实现了 135 倍的加速。对于跨四个工作进程的 2,000 个小任务的并行 map 操作,加速倍数达到 42 倍,将执行时间从 123 毫秒降低到仅 2.9 毫秒。

跨语言互操作性

任务往返比较 (Apple M4 Pro): ProcessPoolExecutor (Python) 94.2 µs; pymizu (Python) 0.7 µs; mizu (R) 0.8 µs; libmizu (C core) 0.4 µs
任务往返比较 (Apple M4 Pro)opensource.posit.co

由 HN Digest 根据 opensource.posit.co 报告的数据绘制;数值与源文件一致。

由于 mizu 和 pymizu 共享相同的 C 核心,它们提供了一种统一的传输格式,允许 R 和 Python 进程直接通信。这支持了一种工作流:R 会话可以将数据框传递给 Python 工作进程使用 Polars 进行处理,结果作为零拷贝的 ALTREP 视图返回。

包括 NumPy 数组、Polars 数据框和 Arrow 表在内的常见数据结构可以在无需编组或转换的情况下跨越边界。在直接发送速度快于小尺寸阈值的情况下,这些对象作为同一内存页的视图进行共享。

当前限制与生命周期

Python 3.10 或更高版本的 Python 版本要求图标
pymizu 软件包要求在 64 位平台上运行 Python 3.10 或更高版本。github.com

该项目需要特定的 Python 版本和 64 位平台才能正常运行。

该项目目前处于实验性生命周期,这意味着 API 尚未稳定,并可能根据用户反馈进行更改。它要求在 64 位平台上运行 Python 3.10 或更高版本,且扩展程序在安装期间会编译随附的 C 核心内容。