تصور کنید سیستمی دارید که برای اجرای یک کوئری، دیگر نیازی نیست تمام دادهها را در رم جای دهد. با عرضه Polars 2.0، پردازش دادهها بهصورت پیشفرض به یک موتور استریمینگ منتقل شده است که در صورت نیاز، دادهها را روی دیسک میریزد تا از کرش کردن سیستم جلوگیری کند. این تغییر، نشاندهنده یک چرخش استراتژیک به سمت تبدیل SQL به یک شهروند درجه اول و اعمال سختگیریهای بیشتر در انواع دادهها برای شتاب بخشیدن به توسعههای مبتنی بر هوش مصنوعی است.
دنیای مهندسی داده سالهاست که میان سرعت بالای حافظه (In-memory) و پایداری دیسک در نوسان است. ابزارهایی مثل Pandas اغلب هنگام مواجهه با فایلهای حجیم متوقف میشدند، در حالی که موتورهای SQL پایداری داشتند اما گاهی انعطافپذیری APIهای DataFrame را نداشتند. Polars در سالهای اخیر روی یک موتور با کارایی بالا متمرکز بود و نسخه ۲.۰ تلاشی است برای ترکیب این سرعت با تابآوری پایگاهدادههای سنتی.
تغییر به سمت پردازش خارج از حافظه (Out-of-Core)
مهمترین تغییر در نسخه ۲.۰، فعالسازی پیشفرض موتور استریمینگ هنگام فراخوانی متد collect روی یک LazyFrame است. این قابلیت اجازه میدهد تا بهبودهای عظیمی در مدیریت حافظه حاصل شود، زیرا موتور اکنون میتواند دادهها را در تکههای کوچک (Chunks) پردازش کند، بهجای آنکه همه چیز را یکباره در رم بارگذاری نماید. این رویکرد بهینهسازی حافظه یادآور تلاشهای مشابه در سایر اکوسیستمهای نرمافزاری است، مانند بازسازی هسته Effect 4.0 که با هدف کاهش شدید مصرف حافظه و حجم باندلها انجام شد.
پشتیبانی از پردازش خارج از حافظه (OOC) یا همان «ریختن روی دیسک» (Spill-to-disk)، اکنون بهصورت پیشفرض فعال است. سیستم زمانی شروع به انتقال دادهها به دیسک میکند که مصرف رم به حدود ۸۰٪ برسد؛ هرچند تیم توسعه اشاره کرده است که این آستانه ممکن است در آینده نیاز به تنظیمات دقیقتری داشته باشد.
در حال حاضر، بودجه پیشفرض دیسک برای این عملیات ۶۴ گیگابایت تعیین شده است. این قابلیت در حال حاضر برای عملیات مرتبسازی (Sort)، توابع پنجرهای (Window Functions) و بسیاری از عبارتها (Expressions) فعال است. در نقشهراه آینده، فعالسازی پشتیبانی OOC برای عملیات Join و Group-by در دستور کار است تا تابآوری در بارهای کاری با مصرف رم بالا برای کاربران عادی افزایش یابد.
یک نکته فنی و تبادل (Trade-off) حیاتی این است که موتور استریمینگ بهصورت پیشفرض ترتیب ردیفها (Row-order) را در برخی عملیاتها، از جمله Join, Group-by و Unpivot تضمین نمیکند. کاربرانی که به ترتیب مشاهدهپذیر ردیفها در این عملیاتها نیاز دارند، باید صراحتاً با تنظیم maintain_order=True این قابلیت را فعال کنند.
عملکرد SQL و بنچمارکها
Polars 2.0 زبان SQL را به عنوان یک رابط کاربری اصلی معرفی میکند که توسط بهبودهای قابل توجه در بهینهساز و موتور پردازشی پشتیبانی میشود. برای تبدیل SQL به یک شهروند درجه اول، تیم توسعه چندین مکانیزم هستهای را پیاده کرده است:
- بازآرایی Joinها (Join reordering)
- حذف پیشرفته زیر-طرحهای مشترک (Enhanced common-subplan-elimination)
- گزارههای پویا (Dynamic predicates) و فیلترهای بلوم (Bloom filters)
برای اثبات این عملکرد، Polars در برابر DuckDB (نسخههای v1.5.6 و 2.0 alpha/2.00.dev2610011535) و DataFusion (نسخه v54.0.0) با استفاده از بنچمارکهای استاندارد TPC-H و TPC-DS1 مورد آزمایش قرار گرفت. این تستها روی نمونههای AWS c7a انجام شد: یک c7a.4xlarge (با ۱۶ vCPU و ۳۲ گیگابایت رم) و یک c7a.metal (با ۱۹۲ vCPU و ۳۸۴ گیگابایت رم).
متدولوژی بنچمارک
برای تضمین دقت، تیم توسعه یک پروتکل تست سختگیرانه را دنبال کرد:
- اجرا: هر کوئری ۵ بار در حالت Hot اجرا شد. برای هر کوئری از یک پروسه مجزا استفاده شد و مهلت زمانی (Timeout) ۶۰ ثانیهای تعیین گردید.
- تولید دادهها: دادهها با استفاده از
tpcgen-cliدر قالب parquet (کامپایل شده از سورس در کامیت 99bedae) تولید و روی EBS ذخیره شدند. - اعتبارسنجی: تایید شد که اندازه گروههای ردیف (Row-group sizes) مشابه با خروجیهای
scan_csvدر Polars (که از طریقsink_parquetمنتقل شده) و دستورCOPYدر DuckDB است. - کوئریها: کوئریهای SQL با استفاده از توابع
tpch_queries()وtpcds_queries()در DuckDB 1.5.6 تولید شدند. - معیارها: بهترین زمان از بین ۵ اجرای هر کوئری انتخاب شد و مقایسه موتورها بر اساس مجموع زمانها و میانگین هندسی زمان اجرای کوئریها صورت گرفت.
طبق گزارش، Polars در تقریباً تمام بنچمارکها سریعترین موتور بود. روی c7a.4xlarge، Polars تمام کوئریها را به پایان رساند، در حالی که DataFusion در کوئری q72 از TPC-DS (و یک بار در q67) دچار Timeout شد و در کوئری q18 از TPC-H با خطای کمبود حافظه (Out of memory) مواجه گشت.
مقیاسپذیری به ۱۹۲ هسته (c7a.metal) نشان داد که Polars در مقیاس SF100، در TPC-H حدود ۳.۸ برابر و در TPC-DS حدود ۲.۲ برابر (بر اساس مجموع زمان) سریعتر از DuckDB 1.5.6 است. برای مقایسه، DuckDB 1.5.6 به بهبودهای ۳.۲ و ۱.۹ برابری رسید، در حالی که DataFusion تنها به ۱.۷ و ۱ برابر دست یافت.
نکته جالب این است که تیم توسعه متوجه یک سربار (Overhead) ثابت هنگام مقیاسپذیری به ۱۹۲ رشته (Thread) شد که به کوئریهای دادههای کوچک آسیب میزند. در مقیاس SF10، هستههای اضافی کمکی به تنظیمات پیشفرض Polars نکردند؛ سرعت در TPC-H یکسان بود و در TPC-DS حدود ۱.۸ برابر کندتر شد. آنها دریافتند که محدود کردن Polars به ۳۲ هسته در واقع آن را در تمام بنچمارکها رقابتی یا برنده میکند؛ باگی که قصد دارند در انتشار بعدی برطرف کنند.
نوع داده جدید Map و سختگیرانه شدن
Polars اکنون بهطور بومی از Arrow MapType در قالب نوع داده pl.Map پشتیبانی میکند. این نوع داده مانند یک دیکشنری پایتون عمل کرده و کلیدها را به مقادیر نگاشت میکند. پیش از این، Arrow MapType بهصورت List(Struct({"key": ..., "value": ...})) خوانده میشد.
اکنون کاربران میتوانند عملیاتهای اختصاصی شبیه به دیکشنری را مستقیماً در API اجرا کنند:
- جستجوی کلید: با استفاده از
.map.get()که هم از کلیدهای ثابت (مثلاً "math") و هم از کلیدهای مشتق شده از ستونهای دیگر پشتیبانی میکند. - اعتبارسنجی کلید: بررسی وجود کلید با
.map.contains_key(). - متاداده: استخراج تعداد عناصر از طریق
.map.len(). - استخراج: بازیابی تمام کلیدها یا مقادیر از طریق
.map.keys()و.map.values().
فراتر از ویژگیها، این کتابخانه «سختگیرتر» شده است. Polars اکنون بهجای تلاش برای تبدیلهای ضمنی (Implicit Conversions) در صورت عدم تطابق دادهها، سریعاً خطا میدهد (Fail fast)، زیرا این تبدیلها میتوانند باگها را پنهان کنند. این تصمیم طراحی بهطور خاص برای کمک به عاملهای هوش مصنوعی (AI Agents) اتخاذ شده است؛ یک عامل میتواند با فراخوانی collect_schema()، انواع دادهها را شناسایی کرده و ساختار کوئری را پیش از متریالیزه کردن هرگونه دادهای اعتبارسنجی کند. این امر بازخورد سریع را تضمین کرده و اجازه میدهد هم عاملها و هم انسانها سریعتر تکرار (Iterate) کنند.
تحلیل: پایان «دیوار رم»
برای یک دانشمند داده در دنیای واقعی، این نسخه بهطور موثری «دیوار رم» (RAM wall) را از بین میبرد. قابلیت ریختن دادهها روی دیسک بهصورت پیشفرض به این معناست که Polars دیگر فقط ابزاری برای کسانی نیست که ایستگاههای کاری گرانقیمت با رم بالا دارند، بلکه برای کاربران عادی روی لپتاپهای استاندارد نیز کاربردی میشود.
با ادغام SQL به عنوان یک شهروند درجه اول و شکست دادن DuckDB در بنچمارکهای رودررو، Polars در حال تبدیل شدن از یک «جایگزین Pandas» به یک موتور پایگاهداده تحلیلی کامل است. تمرکز بر سختگیرانه بودن (Strictness) نیز سیگنالی است که نشان میدهد Polars خود را برای دنیایی آماده میکند که در آن LLMها، و نه انسانها، بخش عمده خط لولههای داده (Data Pipelines) را مینویسند.
در نگاه به آینده، تیم توسعه بر روی قابلیتهای بهتر Out-of-core، بهبود مقیاسپذیری برای تعداد CPUهای بالا و تبدیل Polars Cloud به سریعترین موتور توزیعشده موجود متمرکز است. آنها همچنین کار روی GeoPolars را آغاز کردهاند.
اگر تیم توسعه بتواند سربار تعداد هستههای بالا را حل کند و افزونه GeoPolars را ارائه دهد، Polars میتواند به بکاند پیشفرض برای تقریباً تمام پردازشهای دادههای جدولی در محیطهای محلی و ابری تبدیل شود.
برای شروع مهاجرت، میتوانید راهنمای رسمی مهاجرت را بررسی کنید یا بنچمارکهای جدید را از طریق مخزن عمومی گیتهاب آنها در آدرس https://github.com/pola-rs/polars-2.0-benchmark تست کنید.
گام بعدی شما
- اگر با خطاهای Memory Error در Pandas یا نسخههای قدیمی Polars مواجه بودید، به نسخه ۲.۰ مهاجرت کنید تا از قابلیت Spill-to-disk بهره ببرید.
- برای بهینهسازی کوئریهای SQL خود، مستندات جدید بهینهساز Polars را مطالعه کنید.
- اگر از عاملهای هوش مصنوعی برای تحلیل داده استفاده میکنید، متد
collect_schemaرا برای کاهش نرخ خطای کدها در خط لوله (Pipeline) خود بگنجانید.
اما این تنها بخشی از تحول در پردازش داده است؛ برای درک اینکه چگونه پردازش توزیعشده در ابر تغییر میکند، تحلیل ما درباره Polars Cloud را دنبال کنید.




گفتگو