Principaux ajouts
Polars 2.0 passe en version majeure en intégrant trois changements majeurs : le moteur de streaming devient le comportement par défaut, le support out‑of‑core (spill‑to‑disk) s’active automatiquement à ~80 % de la RAM avec un budget disque de 64 Go, et le type Map d’Arrow est exposé comme dtype Polars. Ces ajouts visent à réduire la consommation mémoire et à élargir les cas d’usage sans modifier le code existant.
Moteur SQL et performances
Le SQL est désormais traité comme une première classe. L’optimiseur a reçu des améliorations : réordonnancement des jointures, élimination de sous‑plans communs et filtres dynamiques/bloom. Les auteurs ont évalué le moteur sur les benchmarks TPC‑H et TPC‑DS 1 en le comparant à DuckDB 1.5.6, DuckDB 2.0 alpha (2.0.0.dev2610011535) et DataFusion 54.0.0. Les tests ont été exécutés sur deux instances : c7a.4xlarge (16 vCPU, 32 Go) et c7a.metal (192 vCPU, 384 Go), chaque requête étant lancée cinq fois en mode chaud. Polars a été le plus rapide sur tous les tests sauf un, mais montre un surcoût constant lorsqu’il exploite les 192 threads, ce qui pénalise les requêtes sur petits jeux de données. Limité à 32 cœurs, Polars reste compétitif voire gagnant sur l’ensemble des benchmarks.
Moteur de streaming et out‑of‑core
Appeler collect() sur un LazyFrame utilise désormais le moteur de streaming, ce qui supprime la nécessité de charger l’ensemble du résultat en mémoire. Le streaming ne garantit pas l’ordre des lignes pour les opérations join, group_by ou unpivot; l’ordre peut être restauré en passant maintain_order=True. Le support out‑of‑core s’applique déjà aux tris, fonctions de fenêtre et à de nombreuses expressions, avec une stratégie de débordement dès que l’utilisation mémoire dépasse 80 % du quota. Les futures versions étendront ce mécanisme aux jointures et aux agrégations de groupe.
Nouveau type Map et gestion stricte des dtypes
df = pl.DataFrame({
"user": ["alice", "bob", "carol"],
"scores": pl.Series([
{"math": 90, "art": 75},
{"math": 60},
{}
], dtype=pl.Map(pl.String, pl.Int64)),
"subject": ["art", "art", "math"]
})
df.select(
"user",
pl.col("scores").map.get("math").alias("math"),
pl.col("scores").map.get(pl.col("subject")).alias("by_subject"),
pl.col("scores").map.contains_key("art").alias("has_art"),
pl.col("scores").map.len().alias("n"),
pl.col("scores").map.keys().alias("keys"),
pl.col("scores").map.values().alias("values")
)
Le dtype Map se comporte comme un dictionnaire Python, offrant des méthodes de recherche de clé, de test d’existence, de comptage et d’extraction des clés/valeurs. Par ailleurs, Polars renforce la stricte validation des dtypes : les incohérences sont détectées tôt, limitant les erreurs d’exécution à la phase de construction du pipeline.