Polars 2.0 发布

查看原文 HN 讨论

文章摘要

Polars 是用 Rust 编写、主要通过 Python 使用的高性能 DataFrame 库,常被视为 pandas 的替代品。创始人 Ritchie Vink 在官方博客宣布 Polars 2.0 正式发布。此前一篇文章已解释过升级大版本号的理由,这篇则专门介绍新功能。作者说,2.0 原本并不打算做成大规模功能更新,但仍然带来不少值得兴奋的内容,主要有五点:默认启用初版的外存(溢出到磁盘)支持、大量核心性能改进、一等公民级的 SQL 支持、新的 Map 数据类型,以及对数据类型更严格、更显式的处理。

SQL 与性能。 2.0 标志着 Polars 正式把 SQL 当作一等公民,过去几个月 SQL 覆盖面大幅扩展。为了让 SQL 跑得快,优化器和执行引擎做了多项改进,重点包括连接重排序、更好的公共子计划消除,以及动态谓词和布隆过滤器。团队在 AWS 的 c7a.4xlarge(16 vCPU、32 GB 内存)和 c7a.metal(192 vCPU、384 GB 内存)上,用基于 TPC-H 和 TPC-DS 生成的数据,将 Polars SQL 与 DuckDB 1.5.6、DuckDB 2.0 alpha 和 DataFusion 54.0.0 对比。每条查询以热缓存方式运行 5 次、取最好成绩,每条查询单独开进程,超时 60 秒;查询语句由 DuckDB 自带函数生成,数据用 DataFusion 团队的生成器制作。结果是:Polars 和两个版本的 DuckDB 跑完了全部查询,DataFusion 有个别查询超时或内存溢出;默认配置的 Polars 在几乎所有基准中最快。唯一的弱项是在 192 线程的大机器上处理小数据量时,Polars 有一段固定开销——限制到 32 线程后反而在所有基准中都有竞争力甚至领先。团队已找到原因,计划下个版本修复,并公开了基准测试仓库供复现。附录还显示,在 SF100 数据规模下从 16 核扩到 192 核,Polars 在 TPC-H 上提速 3.8 倍,扩展性优于其他引擎。

流式引擎与外存成为默认。 这是影响最大的改动:对 LazyFrame 调用 collect 现在默认使用流式引擎,多数查询的内存占用和性能都有大幅改善。之所以需要升级大版本,是因为流式引擎在连接、分组、逆透视等操作中默认不保证行顺序,需要顺序时要显式设置 maintain_order=True。外存功能也默认开启:内存用到约 80% 时开始溢出到磁盘,默认磁盘预算 64 GB;目前排序、窗口函数和许多表达式已支持,连接和分组将在之后跟进。作者认为这会让普通数据从业者在大内存负载下更稳健。

新的 Map 类型。 Polars 现在直接支持 Arrow 的 MapType,可以理解为 Python 字典式的键值映射。此前它会被读成「由 key/value 结构体组成的列表」,现在则有专门的表达式,例如按固定键或按另一列的值取值、判断是否包含某个键、获取键列表和值列表等。

更严格的 Polars。 Polars 的理念是尽早失败:错误应在一开始就抛出,而不是在流水线跑了 20 分钟之后;数据不匹配时的隐式行为应当需要主动开启,而不是默认发生,因为这类行为会掩盖 bug。作者特别指出,在 AI 驱动开发兴起后,这种严格性更有价值——代理可以调用 collect_schema(),在不实际计算数据的情况下解析类型、提前发现模式层面的错误,让人和代理都能更快迭代。

文章最后表示,接下来会继续改进外存支持和大核数扩展性,目标是让 Polars Cloud 成为最快的分布式引擎,同时已经开始开发 GeoPolars,并提供了迁移指南。

HN 评论精华

与 DuckDB 的竞争和基准测试的可信度

Polars 能否完全取代 pandas

其他