programmatūra · 5 min · 16.10.2026

Polars 2.0 padara straumēšanas dzini par noklusējumu: spill uz disku sākas pie 80 % RAM

Kad programmētājs Polars 2.0 bibliotēkā izsauc collect() uz LazyFrame, vaicājums tagad plūst caur straumēšanas dzini. Agrāk tas pašā noklusējumā ielādēja visus datus atmiņā. Ritchie Vink, kurš Polars sāka 2020. gadā, šo maiņu izlaida 6. oktobrī. Tagad straumēšana ir ieslēgta katram slinkajam vaicājumam.

Praksē tas nozīmē, ka tabula vairs netiek apstrādāta vienā gabalā. Dati nāk pa daļām. Dzinis tos virza caur plānu pa posmiem. Atmiņas patēriņš paliek zems arī tad, ja tabula ir lielāka par pieejamo RAM. Lietotājiem, kuri līdz šim ķērās pie collect(streaming=True), šis karodziņš vairs nav vajadzīgs.

Polars ir Rust valodā rakstīta tabulu apstrādes bibliotēka ar Python saskarni. To izmanto datu inženieri, kam gribas pandas stila kodu, taču ātrāku izpildi un zemāku atmiņas patēriņu. Līdz 2.0 lielākie vaicājumi mēdza krist ar atmiņas kļūdu tad, kad tabula neietilpa RAM. Jaunā noklusējuma uzvedība šo scenāriju maina, jo dzinis datus tagad apstrādā pa gabaliem.

Kas mainās pašā noklusējumā

Iepriekš parametrs engine="auto" slinkajiem vaicājumiem izvēlējās atmiņā bāzēto dzini. Tagad tas pats auto izvēlas straumēšanas dzini. Tiešās DataFrame darbības, kas izpildās uzreiz, paliek bez izmaiņām. Maiņa skar tikai to kodu, kurš veido plānu un tad to izpilda ar collect.

Straumēšanas dzinis nav jaunums. Polars to piedāvāja jau vairākas versijas kā izvēles iespēju aiz streaming=True. Līdz šim tas bija eksperimentāls un pilns ar robiem. Versijā 2.0 komanda to atzīst par pietiekami stabilu, lai tas kļūtu par klusējošo izvēli.

Dzinis tagad arī ātrāk met kļūdas. Funkcija collect_schema() ļauj noķert shēmas neatbilstību, pirms tiek materializēts kaut viens datu baits. Vietās, kur kļūda ir atkarīga no pašiem datiem, Polars tagad izvēlas stingrāku rīcību.

Rindu secība vairs nav garantēta

Lielākais slazds slēpjas rindu secībā. Straumēšanas dzinis pēc noklusējuma nesaglabā rindu kārtību operācijās join, group_by un unpivot. Kurš grib veco uzvedību, tam jāpadod maintain_order=True. Vecs kods, kas klusi paļāvās uz stabilu secību, tagad var dot citādu rezultātu bez jebkāda brīdinājuma.

Oficiālā migrācijas pamācība brīdina, ka šī maiņa var klusi ietekmēt jūsu cauruļvadu rezultātus.

Tāpēc jaunināšanas ceļvedis iesaka pārskatīt katru vietu, kur kods pieņem noteiktu rindu kārtību pēc apvienošanas vai grupēšanas.

Spill uz disku un 64 GB budžets

Polars 2.0 pēc noklusējuma ieslēdz arī darbu ārpus atmiņas. Kad patēriņš sasniedz aptuveni 80 % no RAM, dzinis sāk rakstīt starprezultātus uz disku. Noklusētais diska budžets ir 64 GB. Abus skaitļus projekts atzīst par tādiem, ko var nākties piemērot savai mašīnai.

Atbalsts pagaidām sedz kārtošanu, logu funkcijas un daudzas izteiksmes. Apvienošana un grupēšana vēl stāv ārpus šī saraksta, tāpēc viens liels join joprojām var prasīt pietiekami daudz atmiņas. Pilnīga neatkarība no RAM tātad vēl nav sasniegta.

Ātrums pret DuckDB un DataFusion

Projekts mēra sevi ar TPC-H un TPC-DS datiem pret DuckDB 1.5.6, DuckDB 2.0 alfa versiju un DataFusion 54.0.0. Testi gāja uz divām AWS mašīnām: c7a.4xlarge ar 16 vCPU un c7a.metal ar 192 vCPU. Katram vaicājumam tika saglabāts labākais no pieciem karstajiem palaidieniem ar 60 sekunžu limitu.

Mērogojot no 16 uz 192 vCPU pie SF100, Polars kļuva 3,8 reizes ātrāks TPC-H un 2,2 reizes ātrāks TPC-DS. DuckDB 1.5.6 tajā pašā lēcienā ieguva 3,2 un 1,9 reizes, DuckDB 2.0 alfa ieguva 2,2 un 1,5 reizes, bet DataFusion palika pie 1,7 un 1,0 reizes. Mazākā apjomā SF10 aina mainās. Tur Polars TPC-H ir aptuveni vienādi ātrs ar DuckDB, taču TPC-DS ir 1,8 reizes lēnāks. Jaudu Polars tātad izspiež tad, kad datu apjoms un kodolu skaits aug kopā.

Salīdzinājumā ir arī robi. DataFusion TPC-DS vaicājumā q72 pārsniedza laika limitu, bet TPC-H vaicājumā q18 uz mazākās mašīnas tam pietrūka atmiņas. Šos vaicājumus projekts no rezultātiem izņēma visiem dzinējiem, tāpēc skaitļi ir salīdzināmi tikai tajā apjomā, kuru visi četri paspēja izrēķināt.

Ko salabot vecajā kodā

Daļa koda pēc jaunināšanas vienkārši nekompilēsies. Tas ir ar nolūku. Metode melt tagad saucas unpivot. Parametrs join_nulls ir pārdēvēts par nulls_equal. Zudumus nesošas tipu pārveides funkcijā is_in, nesakrītoša garuma horizontāla concat un neskaidras tipu konversijas tagad met kļūdu tā vietā, lai klusi dotu nepareizu atbildi.

Parādījies arī jauns Map datu tips, kas tieši atbilst Arrow MapType. Agrāk tāds lauks tika nolasīts kā List(Struct). Jaunais tips nāk ar metodēm map.get, map.contains_key, map.len, map.keys un map.values. Vink raksta, ka no šīs versijas SQL projektā kļūst par pirmās šķiras pilsoni.

Avoti

komentārisaruna

Komentāri

Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.

Pievieno komentāru

Tavs e-pasts netiks publicēts. Obligātie lauki atzīmēti.

vēl no programmatūrasaistītie