Hub documentation
Tối ưu hóa
Tối ưu hóa
Chúng ta đã đề cập ngắn gọn về sự khác nhau giữa đánh giá lười (lazy) và đánh giá ngay (eager). Trên trang này, chúng ta sẽ cho thấy cách API lười có thể được sử dụng để đạt được lợi ích hiệu năng lớn.
Lazy so với Eager
Polars hỗ trợ hai chế độ hoạt động: lazy và eager. Trong API eager, truy vấn được thực thi ngay lập tức, trong khi trong API lazy, truy vấn chỉ được đánh giá khi thực sự “cần thiết”. Việc trì hoãn việc thực thi đến phút cuối có thể mang lại lợi thế hiệu suất đáng kể, và đây là lý do API lazy được ưu tiên trong hầu hết các trường hợp không tương tác.
Ví dụ
Chúng ta sẽ sử dụng ví dụ từ trang trước để minh họa lợi ích về hiệu năng khi dùng API lazy. Đoạn mã bên dưới sẽ tính toán số lượng tệp tải lên từ 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)Lười
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()Thời gian
Việc chạy cả hai truy vấn dẫn đến thời gian thực hiện như sau trên một chiếc laptop thông thường với kết nối internet gia đình:
- Eager:
1.96giây - Lazy:
410mili giây
Truy vấn lazy nhanh hơn truy vấn eager khoảng 5 lần. Lý do là bộ tối ưu hóa truy vấn: nếu chúng ta trì hoãn việc collect dataset cho đến cuối, Polars sẽ có thể suy luận xem những cột và hàng nào được yêu cầu và áp dụng bộ lọc sớm nhất có thể khi đọc dữ liệu. Đối với các định dạng tệp như Parquet chứa metadata (ví dụ: min, max trong một nhóm hàng nhất định), sự khác biệt thậm chí có thể lớn hơn vì Polars có thể bỏ qua toàn bộ các nhóm hàng dựa trên bộ lọc và metadata mà không cần truyền dữ liệu qua mạng.