You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中两种等价计算方法的并行性能差异与原因探究

Polars两种计算方法的并行性与性能差异分析

先直接给结论:两种方法在并行性上存在差异,方法2性能更优的核心原因是Polars的查询优化器对表达式做了化简,同时避免了中间列的内存开销,而非单线程执行。

一、并行性差异细节

  • 方法1:两次select的执行逻辑是:

    1. 第一步select中,计算x_1 = a+b和x_2 = b+c,这两个计算确实可以并行——因为它们依赖的原始列是独立的,Polars会用多线程同时处理这两个列运算。
    2. 第二步select需要读取第一步生成的两个中间列x_1和x_2,再求和得到target,这一步的列运算本身也是多线程,但需要先从内存加载中间列,有额外开销。
  • 方法2:看似是嵌套表达式,但Polars的Lazy优化器会先对表达式做化简:

    (a + b) + (b + c) → a + 2*b + c
    

    化简后的表达式会拆分为三个独立的列运算:a、2*b、c,这三个部分同样可以并行计算,之后再将结果相加。整个过程没有中间列的存储,直接在原始列上完成所有运算。

二、性能差异的核心原因

  1. 表达式化简减少运算步骤
    方法1需要3次加法运算(a+b、b+c、x1+x2),而方法2被化简后只需要2次核心运算(2*b、a+2b+c),直接减少了一次大规模列运算的开销。

  2. 避免中间列的内存开销
    方法1会生成两个1亿行的中间列x_1和x_2,按int64类型计算,每个列占用800MB内存,两个就是1.6GB。这些中间列需要写入内存再读取,不仅占用额外内存,还会增加内存读写的延迟。而方法2全程不需要存储中间结果,直接在原始列上做计算,内存效率更高。

  3. 缓存友好性提升
    方法2直接操作原始列,数据更容易被CPU缓存命中;方法1的中间列写入内存后,再次读取时可能已经被挤出缓存,导致CPU需要从内存甚至磁盘加载数据,进一步增加延迟。

验证方式

你可以用explain()查看两种方法的优化后查询计划,直观看到差异:

# 查看方法1的计划
print(df.select(x_1=pl.col("a")+pl.col("b"), x_2=pl.col("b")+pl.col("c")).select(target=pl.col("x_1")+pl.col("x_2")).explain())

# 查看方法2的计划
print(df.select(target=(pl.col("a")+pl.col("b"))+(pl.col("b")+pl.col("c"))).explain())

内容的提问来源于stack exchange,提问作者thoooooooomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:45:06