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

Polars单线程下LazyFrame与Eager模式内存占用差异及疑问

Polars LazyFrame 与 Eager 模式内存占用疑问

问题背景

我有若干CSV样例文件,分别用两段Polars代码完成读取、过滤与拼接操作:

LazyFrame版本代码

import os

os.environ["POLARS_MAX_THREADS"] = "1"

import polars as pl

df = pl.concat(
    [
        pl.scan_csv("test.csv").filter(pl.col("x3") > 0),
        pl.scan_csv("test1.csv").filter(pl.col("x3") > 0),
        pl.scan_csv("test2.csv").filter(pl.col("x3") > 0),
    ]
).collect()

Eager模式版本代码

将上述代码中的scan_csv替换为read_csv即可。

原本预期LazyFrame版本内存表现与Eager模式相当,但实际测试中LazyFrame版本内存占用反而更高,且增加核心数后内存占用进一步提升。我通过mprof生成了内存占用随时间变化的图表,现提出两个疑问:

  1. 该mprof图表是否能可靠反映内存占用情况?
  2. 这种内存占用情况是否会得到优化,还是惰性求值机制必然导致此现象?

解答

1. mprof图表的可靠性

mprof生成的内存图表是可靠的。它通过定期采样目标进程的内存使用情况生成数据,能准确捕捉Polars处理数据过程中的内存分配、释放波动,包括Lazy模式下查询执行阶段的内存变化,可作为内存占用分析的有效依据。

2. 内存占用高的原因与优化空间

这种内存占用并非惰性求值机制的必然结果,当前写法存在优化空间:

  • 当前写法的问题:分别对每个CSV文件生成独立的LazyFrame并执行过滤,再通过pl.concat合并后collect。这种情况下Polars的查询优化器无法将多个文件的扫描、过滤、拼接操作合并为一条高效流水线,执行时可能需要同时加载多个文件的中间数据;多线程场景下,并行处理多个文件还会导致内存叠加,进一步推高内存占用。
  • 优化方案:直接将多个CSV文件路径传入pl.scan_csv,再统一执行过滤和收集操作,代码如下:
import os

os.environ["POLARS_MAX_THREADS"] = "1"

import polars as pl

df = pl.scan_csv(["test.csv", "test1.csv", "test2.csv"]) \
       .filter(pl.col("x3") > 0) \
       .collect()

这种写法会让Polars生成单一查询计划,流式处理每个CSV文件,过滤后直接拼接结果,内存占用会和Eager模式相当甚至更低,充分发挥惰性求值的内存优势。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:50:21