Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 2

Leo tunachapisha sehemu ya pili ya tafsiri ya nyenzo kuhusu jinsi Dropbox ilivyopanga udhibiti wa aina kwa mistari milioni kadhaa ya msimbo wa Python.

Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 2

β†’ Soma sehemu ya kwanza

Usaidizi wa aina rasmi (PEP 484)

Tulifanya majaribio yetu mazito ya kwanza na mypy katika Dropbox wakati wa Hack Week 2014. Hack Week ni tukio la wiki moja linalosimamiwa na Dropbox. Wakati huu, wafanyikazi wanaweza kufanya chochote wanachotaka! Baadhi ya miradi maarufu ya teknolojia ya Dropbox ilianza kwenye hafla kama hizi. Kama matokeo ya jaribio hili, tulihitimisha kuwa mypy inaonekana ya kuahidi, ingawa mradi bado hauko tayari kwa matumizi mengi.

Wakati huo, wazo la kusawazisha mifumo ya kuashiria ya aina ya Python ilikuwa angani. Kama nilivyosema, kwa kuwa Python 3.0 iliwezekana kutumia maelezo ya aina kwa kazi, lakini hizi zilikuwa misemo ya kiholela, bila syntax na semantiki iliyofafanuliwa. Wakati wa utekelezaji wa programu, maelezo haya, kwa sehemu kubwa, yalipuuzwa tu. Baada ya Wiki ya Hack, tulianza kufanya kazi ya kusawazisha semantiki. Kazi hii ilisababisha kuibuka PEP 484 (Guido van Rossum, Łukasz Langa na mimi tulishirikiana kwenye waraka huu).

Nia zetu zinaweza kutazamwa kutoka pande mbili. Kwanza, tulitarajia kwamba mfumo mzima wa ikolojia wa Python unaweza kupitisha mbinu ya kawaida ya kutumia vidokezo vya aina (neno linalotumika katika Python kama sawa na "maelezo ya aina"). Hii, kwa kuzingatia hatari zinazowezekana, itakuwa bora kuliko kutumia njia nyingi ambazo haziendani. Pili, tulitaka kujadili kwa uwazi mifumo ya maelezo ya aina na washiriki wengi wa jamii ya Python. Tamaa hii iliagizwa kwa sehemu na ukweli kwamba hatungependa kuonekana kama "waasi-imani" kutoka kwa mawazo ya kimsingi ya lugha machoni pa watu wengi wa programu za Python. Ni lugha iliyochapwa kwa nguvu, inayojulikana kama "kuandika bata". Katika jamii, mwanzoni, mtazamo wa kutiliwa shaka kwa wazo la kuandika tuli haungeweza kusaidia lakini kutokea. Lakini maoni hayo hatimaye yalipungua baada ya kubainika kuwa uchapaji tuli hautakuwa wa lazima (na baada ya watu kugundua kuwa ilikuwa muhimu).

Sintaksia ya kidokezo cha aina ambayo hatimaye ilipitishwa ilikuwa sawa na ile mypy iliunga mkono wakati huo. PEP 484 ilitolewa na Python 3.5 mnamo 2015. Python haikuwa tena lugha iliyochapwa kwa nguvu. Ninapenda kufikiria tukio hili kama hatua muhimu katika historia ya Python.

Kuanza kwa uhamiaji

Mwisho wa 2015, Dropbox iliunda timu ya watu watatu kufanya kazi kwenye mypy. Walijumuisha Guido van Rossum, Greg Price na David Fisher. Kuanzia wakati huo, hali ilianza kukuza haraka sana. Kikwazo cha kwanza kwa ukuaji wa mypy kilikuwa utendaji. Kama nilivyodokeza hapo juu, katika siku za mwanzo za mradi nilifikiria kutafsiri utekelezaji wa mypy hadi C, lakini wazo hili liliondolewa kwenye orodha kwa sasa. Tulikwama kuendesha mfumo kwa kutumia mkalimani wa CPython, ambayo sio haraka vya kutosha kwa zana kama mypy. (Mradi wa PyPy, utekelezaji mbadala wa Python na mkusanyaji wa JIT, haukutusaidia pia.)

Kwa bahati nzuri, baadhi ya maboresho ya algoriti yamekuja kutusaidia hapa. "Kiongeza kasi" cha kwanza chenye nguvu kilikuwa ni utekelezaji wa ukaguzi wa nyongeza. Wazo la uboreshaji huu lilikuwa rahisi: ikiwa utegemezi wote wa moduli haujabadilika tangu wakati uliopita wa mypy, basi tunaweza kutumia data iliyohifadhiwa wakati wa kukimbia hapo awali wakati wa kufanya kazi na utegemezi. Tulihitaji tu kufanya ukaguzi wa aina kwenye faili zilizobadilishwa na kwenye faili ambazo zilitegemea. Mypy hata ilienda mbele kidogo: ikiwa kiolesura cha nje cha moduli hakikubadilika, mypy ilidhani kuwa moduli zingine zilizoingiza moduli hii hazihitaji kuangaliwa tena.

Ukaguzi wa ziada umetusaidia sana wakati wa kubainisha idadi kubwa ya msimbo uliopo. Jambo ni kwamba mchakato huu kawaida hujumuisha utendakazi mwingi wa mypy kwani maelezo yanaongezwa hatua kwa hatua kwenye msimbo na kuboreshwa hatua kwa hatua. Uendeshaji wa kwanza wa mypy bado ulikuwa polepole sana kwa sababu ilikuwa na utegemezi mwingi wa kuangalia. Kisha, ili kuboresha hali hiyo, tulitekeleza utaratibu wa uhifadhi wa mbali. Ikiwa mypy itagundua kuwa kache ya ndani kuna uwezekano kuwa imepitwa na wakati, inapakua picha ya kache ya sasa ya msingi wote wa msimbo kutoka kwa hazina kuu. Kisha hufanya ukaguzi wa nyongeza kwa kutumia muhtasari huu. Hii imetuchukua hatua moja kubwa zaidi kuelekea kuongeza utendaji wa mypy.

Hiki kilikuwa kipindi cha upitishaji wa haraka na wa asili wa kuangalia aina kwenye Dropbox. Kufikia mwisho wa 2016, tayari tulikuwa na takriban mistari 420000 ya msimbo wa Python na maelezo ya aina. Watumiaji wengi walikuwa na shauku juu ya kuangalia aina. Timu zaidi na zaidi za maendeleo zilikuwa zikitumia Dropbox mypy.

Kila kitu kilionekana kizuri wakati huo, lakini bado tulikuwa na mengi ya kufanya. Tulianza kufanya uchunguzi wa mara kwa mara wa watumiaji wa ndani ili kubaini maeneo yenye matatizo ya mradi na kuelewa ni masuala gani yanahitaji kutatuliwa kwanza (zoezi hili bado linatumika katika kampuni leo). Muhimu zaidi, kama ilivyokuwa wazi, ni kazi mbili. Kwanza, tulihitaji chanjo ya aina zaidi ya nambari, pili, tulihitaji mypy kufanya kazi haraka. Ilikuwa wazi kabisa kwamba kazi yetu ya kuharakisha mypy na kuitekeleza katika miradi ya kampuni ilikuwa bado haijakamilika. Sisi, tukifahamu kikamilifu umuhimu wa kazi hizi mbili, tuliamua kuzitatua.

Tija zaidi!

Ukaguzi wa ongezeko ulifanya mypy haraka, lakini chombo bado hakikuwa na kasi ya kutosha. Ukaguzi mwingi wa nyongeza ulichukua takriban dakika moja. Sababu ya hii ilikuwa uagizaji wa mzunguko. Labda hii haitashangaza mtu yeyote ambaye amefanya kazi na codebases kubwa zilizoandikwa kwenye Python. Tulikuwa na seti za mamia ya moduli, ambazo kila moja iliagiza nyingine zote kwa njia isiyo ya moja kwa moja. Ikiwa faili yoyote kwenye kitanzi cha kuagiza ilibadilishwa, mypy ililazimika kusindika faili zote kwenye kitanzi hicho, na mara nyingi moduli zozote zilizoingiza moduli kutoka kwa kitanzi hicho. Mzunguko mmoja kama huo ulikuwa "tangle ya utegemezi" ambayo ilisababisha shida nyingi kwenye Dropbox. Mara tu muundo huu ulikuwa na moduli mia kadhaa, wakati uliingizwa, moja kwa moja au moja kwa moja, vipimo vingi, pia ilitumiwa katika kanuni za uzalishaji.

Tulizingatia uwezekano wa "kuondoa" utegemezi wa mviringo, lakini hatukuwa na rasilimali za kuifanya. Kulikuwa na msimbo mwingi sana ambao hatukuwa tunaufahamu. Kama matokeo, tulikuja na njia mbadala. Tuliamua kufanya kazi ya mypy haraka hata mbele ya "tangles za utegemezi". Tulifikia lengo hili kwa kutumia mypy daemon. Daemon ni mchakato wa seva unaotekelezea uwezo wawili wa kuvutia. Kwanza, huhifadhi habari kuhusu codebase nzima kwenye kumbukumbu. Hii inamaanisha kuwa kila wakati unapoendesha mypy, sio lazima upakie data iliyohifadhiwa inayohusiana na maelfu ya utegemezi ulioingizwa. Pili, yeye kwa uangalifu, katika kiwango cha vitengo vidogo vya kimuundo, anachambua utegemezi kati ya kazi na vyombo vingine. Kwa mfano, ikiwa kazi foo huita kazi bar, basi kuna utegemezi foo kutoka bar. Wakati faili inabadilika, daemon kwanza, kwa kutengwa, huchakata faili iliyobadilishwa tu. Kisha inaangalia mabadiliko yanayoonekana nje ya faili hiyo, kama vile saini za utendaji zilizobadilishwa. Daemon hutumia maelezo ya kina kuhusu uagizaji pekee ili kuangalia mara mbili chaguo za kukokotoa ambazo hutumia kitendakazi kilichorekebishwa. Kwa kawaida, kwa mbinu hii, unapaswa kuangalia kazi chache sana.

Utekelezaji wa haya yote haikuwa rahisi, kwani utekelezaji wa awali wa mypy ulilenga sana kuchakata faili moja kwa wakati mmoja. Tulilazimika kushughulika na hali nyingi za mpaka, tukio ambalo lilihitaji ukaguzi wa mara kwa mara katika hali ambapo kitu kilibadilika katika msimbo. Kwa mfano, hii hutokea wakati darasa limepewa darasa jipya la msingi. Mara tu tulipofanya tulichotaka, tuliweza kupunguza muda wa utekelezaji wa ukaguzi wa nyongeza hadi sekunde chache. Huu ulionekana kuwa ushindi mkubwa kwetu.

Hata tija zaidi!

Pamoja na kache ya mbali ambayo nilijadili hapo juu, daemon ya mypy karibu ilitatua kabisa shida zinazotokea wakati programu huendesha ukaguzi wa aina mara kwa mara, na kufanya mabadiliko kwa idadi ndogo ya faili. Walakini, utendakazi wa mfumo katika hali mbaya ya utumiaji bado ulikuwa mbali na bora. Uanzishaji safi wa mypy unaweza kuchukua zaidi ya dakika 15. Na hii ilikuwa zaidi ya vile tungefurahiya. Kila wiki hali ilizidi kuwa mbaya kwani waandaaji wa programu waliendelea kuandika nambari mpya na kuongeza maelezo kwa nambari iliyopo. Watumiaji wetu bado walikuwa na njaa ya utendakazi zaidi, lakini tulifurahi kukutana nao katikati.

Tuliamua kurudi kwenye mojawapo ya mawazo ya awali kuhusu mypy. Yaani, kubadilisha nambari ya Python kuwa nambari ya C. Majaribio ya Cython (mfumo unaokuruhusu kutafsiri msimbo ulioandikwa kwa Python hadi C) haukutupatia kasi yoyote inayoonekana, kwa hivyo tuliamua kufufua wazo la kuandika mkusanyaji wetu wenyewe. Kwa kuwa kanuni ya mypy (iliyoandikwa katika Python) tayari ina maelezo yote muhimu ya aina, tulifikiri itakuwa vyema kujaribu kutumia maelezo haya ili kuharakisha mfumo. Niliunda haraka mfano ili kujaribu wazo hili. Ilionyesha ongezeko la zaidi ya mara 10 la utendakazi kwenye alama ndogondogo mbalimbali. Wazo letu lilikuwa kukusanya moduli za Python kwa moduli za C kwa kutumia Cython, na kugeuza maelezo ya aina kuwa ukaguzi wa aina ya wakati (kawaida maelezo ya aina hupuuzwa wakati wa kukimbia na hutumiwa tu na mifumo ya ukaguzi wa aina). Kwa kweli tulipanga kutafsiri utekelezaji wa mypy kutoka kwa Python hadi kwa lugha ambayo iliundwa kuandikwa kwa takwimu, ambayo ingeonekana (na, kwa sehemu kubwa, kufanya kazi) kama Python. (Aina hii ya uhamaji wa lugha-mtambuka imekuwa kitu cha jadi ya mradi wa mypy. Utekelezaji wa awali wa mypy uliandikwa kwa Alore, kisha kulikuwa na mseto wa kisintaksia wa Java na Python).

Kuzingatia API ya kiendelezi ya CPython ilikuwa ufunguo wa kutopoteza uwezo wa usimamizi wa mradi. Hatukuhitaji kutekeleza mashine pepe au maktaba yoyote ambayo mypy ilihitaji. Kwa kuongezea, bado tungekuwa na ufikiaji wa mfumo mzima wa ikolojia wa Python na zana zote (kama vile pytest). Hii ilimaanisha kuwa tunaweza kuendelea kutumia msimbo wa Python uliotafsiriwa wakati wa ukuzaji, ikituruhusu kuendelea kufanya kazi na muundo wa haraka sana wa kufanya mabadiliko ya nambari na kuijaribu, badala ya kungoja msimbo utungwe. Ilionekana kana kwamba tulikuwa tukifanya kazi nzuri ya kukaa kwenye viti viwili, kwa kusema, na tuliipenda.

Mkusanyaji, ambao tuliuita mypyc (kwani hutumia mypy kama mwisho wa kuchambua aina), iligeuka kuwa mradi uliofanikiwa sana. Kwa jumla, tulipata takriban kasi 4x kwa ukimbiaji wa mara kwa mara wa mypy bila kache. Kuendeleza msingi wa mradi wa mypyc kulichukua timu ndogo ya Michael Sullivan, Ivan Levkivsky, Hugh Hahn, na mimi kuhusu miezi 4 ya kalenda. Kiasi hiki cha kazi kilikuwa kidogo zaidi kuliko kile ambacho kingehitajika kuandika tena mypy, kwa mfano, katika C ++ au Go. Na ilitubidi kufanya mabadiliko machache zaidi kwenye mradi kuliko tungelazimika kufanya wakati wa kuuandika upya katika lugha nyingine. Pia tulitarajia kwamba tunaweza kuleta mypyc kwa kiwango ambacho watengenezaji programu wengine wa Dropbox wangeweza kuitumia kukusanya na kuharakisha nambari zao.

Ili kufikia kiwango hiki cha utendakazi, tulilazimika kutumia masuluhisho kadhaa ya kuvutia ya uhandisi. Kwa hivyo, mkusanyaji anaweza kuharakisha shughuli nyingi kwa kutumia haraka, ngazi ya chini ya ujenzi wa C. Kwa mfano, simu ya kazi iliyokusanywa inatafsiriwa kwenye simu ya kazi ya C. Na simu kama hiyo ni haraka sana kuliko kuita kazi iliyotafsiriwa. Baadhi ya shughuli, kama vile utafutaji wa kamusi, bado zilihusika kutumia simu za kawaida za C-API kutoka CPython, ambazo zilikuwa na kasi kidogo tu zilipokusanywa. Tuliweza kuondokana na mzigo wa ziada kwenye mfumo ulioundwa na tafsiri, lakini hii katika kesi hii ilitoa faida ndogo tu kwa suala la utendaji.

Ili kutambua shughuli za kawaida za "polepole", tulifanya uwekaji wasifu wa msimbo. Tukiwa na data hii, tulijaribu kubadilisha mypyc ili iweze kutoa nambari ya C haraka kwa shughuli kama hizo, au kuandika tena nambari inayolingana ya Python kwa kutumia shughuli za haraka (na wakati mwingine hatukuwa na suluhisho rahisi la kutosha kwa hiyo au shida nyingine) . Kuandika tena nambari ya Python mara nyingi ilikuwa suluhisho rahisi kwa shida kuliko kuwa na mkusanyaji afanye mabadiliko sawa. Kwa muda mrefu, tulitaka kuhariri mabadiliko mengi haya, lakini wakati huo tulilenga kuharakisha mypy kwa bidii kidogo. Na katika kuelekea lengo hili, tunapunguza pembe kadhaa.

Kuendelea ...

Ndugu wasomaji! Je, ulikuwa maoni gani kuhusu mradi wa mypy ulipojifunza kuwepo kwake?

Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 2
Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 2

Chanzo: mapenzi.com

Kuongeza maoni