Hub documentation
Оптимизации
Оптимизации
Мы кратко коснулись различий между ленивой и немедленной оценкой. На этой странице мы покажем, как ленивый API позволяет получить значительный прирост производительности.
Ленивое и немедленное
Polars поддерживает два режима работы: lazy и eager. В eager API запрос выполняется немедленно, тогда как в lazy API запрос вычисляется только тогда, когда он становится «необходимым». Откладывание выполнения до последнего момента может дать значительное преимущество в производительности, поэтому в большинстве неинтерактивных сценариев предпочтительнее использовать lazy API.
Пример
Мы будем использовать пример со страницы выше, чтобы продемонстрировать преимущества производительности при использовании ленивого 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секунд - Ленивая:
410миллисекунд
Ленивый запрос выполняется примерно в 5 раз быстрее, чем немедленный. Причина в оптимизаторе запросов: если отложить вызов collect для набора данных до конца, Polars сможет определить, какие столбцы и строки необходимы, и применить фильтры как можно раньше при чтении данных. Для форматов файлов, таких как Parquet, содержащих метаданные (например, min, max в определённой группе строк), разница может быть ещё больше, поскольку Polars способен пропускать целые группы строк на основе фильтров и метаданных, не передавая данные по сети.