Hub documentation

最適化

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

最適化

ここでは、遅延評価と即時評価の違いについて簡単に触れました。このページでは、遅延APIを使用して大幅なパフォーマンス向上を実現する方法を示します。

Lazy と Eager

Polarsは、lazy(遅延評価)とeager(即時評価)の2つの動作モードをサポートしています。eager APIではクエリが即座に実行されますが、lazy APIではクエリが「必要とされた」時点で初めて評価されます。実行を可能な限り遅らせることで、大幅なパフォーマンス上の利点を得られることがあり、これがほとんどの対話的でないケースでlazy APIが推奨される理由です。

例

前ページの例を用いて、lazy APIを使用する際の性能上の利点を示します。以下のコードは、archive.orgからのアップロード回数を計算します。

Eager

import polars as pl
import datetime

df = pl.read_csv("hf://datasets/commoncrawl/statistics/tlds.csv", try_parse_dates=True)

df = df.select("suffix", "crawl", "date", "tld", "pages", "domains")
df = df.filter(
    (pl.col("date") >= datetime.date(2020, 1, 1)) |
    pl.col("crawl").str.contains("CC")
)
df = df.with_columns(
    (pl.col("pages") / pl.col("domains")).alias("pages_per_domain")
)
df = df.group_by("tld", "date").agg(
    pl.col("pages").sum(),
    pl.col("domains").sum(),
)
df = df.group_by("tld").agg(
    pl.col("date").unique().count().alias("number_of_scrapes"),
    pl.col("domains").mean().alias("avg_number_of_domains"),
    pl.col("pages").sort_by("date").pct_change().mean().alias("avg_page_growth_rate"),
).sort("avg_number_of_domains", descending=True).head(10)

遅延

import polars as pl
import datetime

lf = (
    pl.scan_csv("hf://datasets/commoncrawl/statistics/tlds.csv", try_parse_dates=True)
    .filter(
        (pl.col("date") >= datetime.date(2020, 1, 1)) |
        pl.col("crawl").str.contains("CC")
    ).with_columns(
        (pl.col("pages") / pl.col("domains")).alias("pages_per_domain")
    ).group_by("tld", "date").agg(
        pl.col("pages").sum(),
        pl.col("domains").sum(),
    ).group_by("tld").agg(
        pl.col("date").unique().count().alias("number_of_scrapes"),
        pl.col("domains").mean().alias("avg_number_of_domains"),
        pl.col("pages").sort_by("date").pct_change().mean().alias("avg_page_growth_rate"),
    ).sort("avg_number_of_domains", descending=True).head(10)
)
df = lf.collect()

タイミング

両方のクエリを実行すると、家庭用インターネット接続を備えた一般的なラップトップで、以下の実行時間が得られます。

  • Eager: 1.96秒
  • Lazy: 410 ミリ秒

遅延クエリは即時クエリよりも約5倍速いです。その理由はクエリオプティマイザーにあります。データセットのcollectを最後まで遅延させることで、Polarsはどの列と行が必要かを推論し、データ読み取り時にフィルタをできるだけ早く適用できるようになります。メタデータ(特定の行グループ内のminやmaxなど)を含むParquetなどのファイル形式では、Polarsがフィルタとメタデータに基づいてデータを送信せずに行グループ全体をスキップできるため、差はさらに大きくなる可能性があります。

Update on GitHub