{"id":38479,"date":"2019-10-31T22:23:56","date_gmt":"2019-10-31T19:23:56","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\/"},"modified":"2019-10-31T22:23:56","modified_gmt":"2019-10-31T19:23:56","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","title":{"rendered":"Rruga drejt kontrollit t\u00eb tipeve n\u00eb 4 milion\u00eb rreshta kodi Python. Pjesa 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Sot publikojm\u00eb pjes\u00ebn e dyt\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit mbi m\u00ebnyr\u00ebn se si Dropbox organizoi kontrollin e tipeve p\u00ebr disa miliona rreshta kodi Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\"><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve n\u00eb 4 milion\u00eb rreshta kodi Python. Pjesa 2\" src=\"\/wp-content\/uploads\/2019\/09\/3f8f396d724153a0374a3fadca190d55.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">Lexoni pjes\u00ebn e par\u00eb<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Mb\u00ebshtetja zyrtare p\u00ebr tipet (PEP 484)<\/h2>\n<p>\nEksperimentet e para serioze me mypy n\u00eb Dropbox i zhvilluam gjat\u00eb Hack Week 2014. Hack Week \u00ebsht\u00eb nj\u00eb aktivitet nj\u00ebjavor q\u00eb organizohet nga Dropbox. Gjat\u00eb k\u00ebsaj kohe, punonj\u00ebsit mund t\u00eb punojn\u00eb mbi \u00e7far\u00eb t\u00eb duan! Disa nga projektet m\u00eb t\u00eb njohura teknologjike t\u00eb Dropbox kan\u00eb nisur pik\u00ebrisht n\u00eb ngjarje t\u00eb tilla. Si rezultat i k\u00ebtij eksperimenti, arrit\u00ebm n\u00eb p\u00ebrfundimin se mypy dukej premtues, megjith\u00ebse n\u00eb at\u00eb koh\u00eb ky projekt ende nuk ishte gati p\u00ebr p\u00ebrdorim t\u00eb gjer\u00eb.<\/p>\n<p>N\u00eb at\u00eb koh\u00eb po qarkullonte ideja e standardizimit t\u00eb sistemeve t\u00eb sugjerimeve p\u00ebr tipet n\u00eb Python. Si\u00e7 e kam p\u00ebrmendur edhe m\u00eb par\u00eb, q\u00eb nga Python 3.0 mund t\u00eb p\u00ebrdoreshin anotimet e tipeve p\u00ebr funksionet, por ato ishin thjesht shprehje arbitrare, pa sintaks\u00eb dhe semantik\u00eb t\u00eb p\u00ebrcaktuar. Gjat\u00eb ekzekutimit t\u00eb programit, k\u00ebto anotime, n\u00eb pjes\u00ebn m\u00eb t\u00eb madhe, thjesht injoroheshin. Pas Hack Week, ne filluam t\u00eb punonim p\u00ebr standardizimin e semantik\u00ebs. Kjo pun\u00eb \u00e7oi n\u00eb krijimin e <noindex><a rel=\"nofollow\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0484\/\">PEP 484<\/a><\/noindex> (n\u00eb k\u00ebt\u00eb dokument punuam s\u00eb bashku Guido van Rossum, \u0141ukasz Langa dhe un\u00eb).<\/p>\n<p>Motivet tona mund t\u00eb shiheshin nga dy k\u00ebndv\u00ebshtrime. S\u00eb pari, shpresonim q\u00eb i gjith\u00eb ekosistemi Python t\u00eb mund t\u00eb pranonte nj\u00eb qasje t\u00eb p\u00ebrbashk\u00ebt p\u00ebr p\u00ebrdorimin e type hints (term q\u00eb p\u00ebrdoret n\u00eb Python si ekuivalent i \u00abanotimeve t\u00eb tipeve\u00bb). Duke marr\u00eb parasysh rreziqet e mundshme, kjo do t\u00eb ishte m\u00eb mir\u00eb sesa p\u00ebrdorimi i shum\u00eb qasjeve t\u00eb papajtueshme mes tyre. S\u00eb dyti, donim t\u00eb diskutonim hapur mekanizmat e anotimit t\u00eb tipeve me shum\u00eb p\u00ebrfaq\u00ebsues t\u00eb komunitetit Python. Pjes\u00ebrisht, kjo d\u00ebshir\u00eb buronte nga fakti q\u00eb nuk donim t\u00eb dukeshim si \u00abtradhtar\u00eb\u00bb t\u00eb ideve themelore t\u00eb gjuh\u00ebs n\u00eb syt\u00eb e mas\u00ebs s\u00eb gjer\u00eb t\u00eb programuesve Python. Kjo \u00ebsht\u00eb nj\u00eb gjuh\u00eb me tipizim dinamik, e njohur p\u00ebr \u00abduck typing\u00bb. N\u00eb komunitet, q\u00eb n\u00eb fillim, ishte e pashmangshme t\u00eb shfaqej nj\u00eb q\u00ebndrim disi i dyshimt\u00eb ndaj ides\u00eb s\u00eb tipizimit statik. Por me kalimin e koh\u00ebs kjo qasje u zbut, pasi u b\u00eb e qart\u00eb se tipizimi statik nuk planifikohej t\u00eb b\u00ebhej i detyruesh\u00ebm (dhe pasi njer\u00ebzit e kuptuan se ai ishte v\u00ebrtet i dobish\u00ebm).<\/p>\n<p>Sintaksa e type hints q\u00eb u miratua p\u00ebrfundimisht ishte shum\u00eb e ngjashme me at\u00eb q\u00eb n\u00eb at\u00eb koh\u00eb mb\u00ebshtetej nga mypy. Dokumenti PEP 484 u publikua s\u00eb bashku me Python 3.5 n\u00eb vitin 2015. Python nuk ishte m\u00eb nj\u00eb gjuh\u00eb q\u00eb mb\u00ebshteste vet\u00ebm tipizimin dinamik. M\u00eb p\u00eblqen ta shoh k\u00ebt\u00eb ngjarje si nj\u00eb pik\u00eb kthese t\u00eb r\u00ebnd\u00ebsishme n\u00eb historin\u00eb e Python.<\/p>\n<h2>Fillimi i migrimit<\/h2>\n<p>\nN\u00eb fund t\u00eb vitit 2015, n\u00eb Dropbox u krijua nj\u00eb ekip prej tre personash p\u00ebr t\u00eb punuar mbi mypy. Ai p\u00ebrb\u00ebhej nga Guido van Rossum, Greg Price dhe David Fisher. Q\u00eb nga ai moment, zhvillimet nis\u00ebn t\u00eb p\u00ebrshpejtoheshin jasht\u00ebzakonisht shum\u00eb. Pengesa e par\u00eb n\u00eb rrug\u00ebn e rritjes s\u00eb mypy ishte performanca. Si\u00e7 e kam l\u00ebn\u00eb t\u00eb kuptohet m\u00eb sip\u00ebr, n\u00eb faz\u00ebn e hershme t\u00eb projektit kisha menduar ta kaloja implementimin e mypy n\u00eb gjuh\u00ebn C, por ajo ide ishte l\u00ebn\u00eb p\u00ebr momentin m\u00ebnjan\u00eb. Mbet\u00ebm t\u00eb kufizuar nga fakti q\u00eb sistemi ekzekutohej nga interpretuesi CPython, i cili nuk ofron shpejt\u00ebsin\u00eb e nevojshme p\u00ebr mjete si mypy. (As projekti PyPy, nj\u00eb implementim alternativ i Python me JIT compiler, nuk na ndihmoi.)<\/p>\n<p>P\u00ebr fat, k\u00ebtu na ndihmuan disa p\u00ebrmir\u00ebsime algoritmike. \u201cP\u00ebrshpejtuesi\u201d i par\u00eb i fuqish\u00ebm ishte zbatimi i kontrollit inkremental. Ideja e k\u00ebtij p\u00ebrmir\u00ebsimi ishte e thjesht\u00eb: n\u00ebse t\u00eb gjitha var\u00ebsit\u00eb e modulit nuk kishin ndryshuar q\u00eb nga ekzekutimi i m\u00ebparsh\u00ebm i mypy, at\u00ebher\u00eb gjat\u00eb pun\u00ebs me var\u00ebsit\u00eb mund t\u00eb p\u00ebrdornim t\u00eb dh\u00ebnat e ruajtura n\u00eb cache nga sesioni i m\u00ebparsh\u00ebm. Na duhej vet\u00ebm t\u00eb b\u00ebnim kontrollin e tipeve n\u00eb skedar\u00ebt e ndryshuar dhe n\u00eb ata skedar\u00eb q\u00eb vareshin prej tyre. Mypy shkoi edhe pak m\u00eb tej: n\u00ebse nd\u00ebrfaqja e jashtme e modulit nuk kishte ndryshuar, mypy konsideronte se modulet e tjera q\u00eb e importonin at\u00eb modul nuk kishin nevoj\u00eb t\u00eb kontrolloheshin s\u00ebrish.<\/p>\n<p>Kontrolli inkremental na ndihmoi shum\u00eb gjat\u00eb anotimit t\u00eb v\u00ebllimeve t\u00eb m\u00ebdha t\u00eb kodit ekzistues. Arsyeja \u00ebsht\u00eb se ky proces zakonisht p\u00ebrfshin shum\u00eb ekzekutime t\u00eb p\u00ebrs\u00ebritura t\u00eb mypy, sepse anotimet shtohen gradualisht n\u00eb kod dhe p\u00ebrmir\u00ebsohen hap pas hapi. Ekzekutimi i par\u00eb i mypy mbetej ende shum\u00eb i ngadalt\u00eb, sepse gjat\u00eb tij duhej t\u00eb kontrolloheshin shum\u00eb var\u00ebsi. P\u00ebr ta p\u00ebrmir\u00ebsuar k\u00ebt\u00eb situat\u00eb, ne zbatuam nj\u00eb mekaniz\u00ebm t\u00eb cache-it n\u00eb distanc\u00eb. N\u00ebse mypy zbulon se cache-i lokal ka shum\u00eb gjasa t\u00eb jet\u00eb i vjetruar, ai shkarkon nj\u00eb snapshot aktual t\u00eb cache-it p\u00ebr t\u00eb gjith\u00eb baz\u00ebn e kodit nga nj\u00eb depo qendrore. M\u00eb pas, duke p\u00ebrdorur k\u00ebt\u00eb snapshot, ai kryen kontrollin inkremental. Kjo na \u00e7oi edhe nj\u00eb hap t\u00eb r\u00ebnd\u00ebsish\u00ebm p\u00ebrpara n\u00eb rritjen e performanc\u00ebs s\u00eb mypy.<\/p>\n<p>Kjo ishte nj\u00eb periudh\u00eb e p\u00ebrhapjes s\u00eb shpejt\u00eb dhe natyrshme t\u00eb sistemit t\u00eb kontrollit t\u00eb tipeve n\u00eb Dropbox. Deri n\u00eb fund t\u00eb vitit 2016, ne kishim tashm\u00eb rreth 420000 rreshta kodi Python me anotime tipesh. Shum\u00eb p\u00ebrdorues e prit\u00ebn me entuziaz\u00ebm kontrollin e tipeve. N\u00eb Dropbox, gjithnj\u00eb e m\u00eb shum\u00eb ekipe zhvilluesish po p\u00ebrdornin mypy.<\/p>\n<p>N\u00eb at\u00eb koh\u00eb gjith\u00e7ka dukej mir\u00eb, por na mbetej ende shum\u00eb pun\u00eb p\u00ebr t\u00eb b\u00ebr\u00eb. Nis\u00ebm t\u00eb zhvillonim sondazhe periodike t\u00eb brendshme me p\u00ebrdoruesit p\u00ebr t\u00eb identifikuar pikat problematike t\u00eb projektit dhe p\u00ebr t\u00eb kuptuar cilat \u00e7\u00ebshtje duhej t\u00eb zgjidheshin t\u00eb parat (kjo praktik\u00eb p\u00ebrdoret n\u00eb kompani edhe sot). Si\u00e7 u b\u00eb e qart\u00eb, m\u00eb t\u00eb r\u00ebnd\u00ebsishmet ishin dy detyra. E para ishte zgjerimi i mbulimit t\u00eb kodit me tipe, e dyta ishte q\u00eb mypy t\u00eb punonte m\u00eb shpejt. Ishte krejt e qart\u00eb se puna jon\u00eb p\u00ebr p\u00ebrshpejtimin e mypy dhe p\u00ebr ta integruar at\u00eb n\u00eb projektet e kompanis\u00eb ishte ende larg p\u00ebrfundimit. Duke e kuptuar plot\u00ebsisht r\u00ebnd\u00ebsin\u00eb e k\u00ebtyre dy detyrave, iu p\u00ebrvesh\u00ebm zgjidhjes s\u00eb tyre.<\/p>\n<h2>M\u00eb shum\u00eb performanc\u00eb!<\/h2>\n<p>\nKontrollet inkrementale e p\u00ebrshpejtuan mypy, por ky mjet ende nuk ishte mjaftuesh\u00ebm i shpejt\u00eb. Shum\u00eb kontrolle inkrementale zgjatnin rreth nj\u00eb minut\u00eb. Shkaku i k\u00ebsaj ishin importet ciklike. Kjo, me gjas\u00eb, nuk do t\u00eb habis\u00eb ask\u00ebnd q\u00eb ka punuar me baza t\u00eb m\u00ebdha kodi t\u00eb shkruara n\u00eb Python. Kishim grupe me qindra module, ku secili prej tyre importonte t\u00ebrthorazi t\u00eb gjith\u00eb t\u00eb tjer\u00ebt. N\u00ebse ndryshohej ndonj\u00eb skedar brenda ciklit t\u00eb importeve, mypy duhej t\u00eb p\u00ebrpunonte t\u00eb gjith\u00eb skedar\u00ebt q\u00eb b\u00ebnin pjes\u00eb n\u00eb at\u00eb cik\u00ebl dhe shpesh edhe \u00e7do modul q\u00eb importonte module nga ai cik\u00ebl. Nj\u00eb nga k\u00ebto cikle ishte \u201cnyja e famshme e var\u00ebsive\u201d, e cila u b\u00eb shkak p\u00ebr shum\u00eb probleme n\u00eb Dropbox. N\u00eb nj\u00eb moment, kjo struktur\u00eb p\u00ebrfshinte disa qindra module; nd\u00ebrkoh\u00eb importohej, drejtp\u00ebrdrejt ose t\u00ebrthorazi, nga shum\u00eb teste dhe p\u00ebrdorej edhe n\u00eb kodin e prodhimit.<\/p>\n<p>Shqyrtuam mund\u00ebsin\u00eb e \u00abzgjidhjes\u00bb s\u00eb var\u00ebsive ciklike, por nuk kishim burime t\u00eb mjaftueshme p\u00ebr ta b\u00ebr\u00eb k\u00ebt\u00eb. Kishte tep\u00ebr shum\u00eb kod me t\u00eb cilin nuk ishim t\u00eb njohur. N\u00eb fund, kaluam te nj\u00eb qasje alternative. Vendos\u00ebm ta b\u00ebjm\u00eb mypy t\u00eb funksionoj\u00eb shpejt edhe kur ka \u00abnyje var\u00ebsish\u00bb. K\u00ebt\u00eb e arrit\u00ebm me demonin mypy. Demoni \u00ebsht\u00eb nj\u00eb proces serveri q\u00eb ofron dy mund\u00ebsi interesante. S\u00eb pari, ai mban n\u00eb memorie informacion p\u00ebr t\u00eb gjith\u00eb baz\u00ebn e kodit. Kjo do t\u00eb thot\u00eb se n\u00eb \u00e7do ekzekutim t\u00eb mypy nuk ka nevoj\u00eb t\u00eb ngarkohen t\u00eb dh\u00ebnat e ruajtura n\u00eb cache q\u00eb lidhen me mij\u00ebra var\u00ebsi t\u00eb importuara. S\u00eb dyti, ai analizon me kujdes, deri n\u00eb nivel nj\u00ebsish shum\u00eb t\u00eb imta strukturore, var\u00ebsit\u00eb midis funksioneve dhe entiteteve t\u00eb tjera. P\u00ebr shembull, n\u00ebse funksioni <code>foo<\/code> th\u00ebrret funksionin <code>bar<\/code>, at\u00ebher\u00eb ekziston nj\u00eb var\u00ebsi <code>foo<\/code> nga <code>bar<\/code>. Kur ndryshon nj\u00eb skedar, demoni fillimisht p\u00ebrpunon n\u00eb izolim vet\u00ebm skedarin e ndryshuar. M\u00eb pas ai shqyrton ndryshimet e k\u00ebtij skedari q\u00eb jan\u00eb t\u00eb dukshme nga jasht\u00eb, si p.sh. n\u00ebnshkrimet e funksioneve q\u00eb kan\u00eb ndryshuar. Demoni p\u00ebrdor informacion t\u00eb detajuar mbi importet vet\u00ebm p\u00ebr t\u00eb rikontrolluar ato funksione q\u00eb e p\u00ebrdorin realisht funksionin e ndryshuar. Zakonisht, me k\u00ebt\u00eb qasje, duhen kontrolluar shum\u00eb pak funksione.<\/p>\n<p>Zbatimi i gjith\u00eb k\u00ebsaj nuk ishte i leht\u00eb, pasi implementimi fillestar i mypy ishte shum\u00eb i orientuar drejt p\u00ebrpunimit t\u00eb nj\u00eb skedari n\u00eb t\u00eb nj\u00ebjt\u00ebn koh\u00eb. Na u desh t\u00eb p\u00ebrballeshim me shum\u00eb raste kufitare, shfaqja e t\u00eb cilave k\u00ebrkonte rikontrolle sa her\u00eb q\u00eb ndryshonte di\u00e7ka n\u00eb kod. P\u00ebr shembull, kjo ndodh kur nj\u00eb klase i caktohet nj\u00eb klas\u00eb baz\u00eb e re. Pasi arrit\u00ebm at\u00eb q\u00eb synonim, mund\u00ebm ta ulim koh\u00ebn e ekzekutimit t\u00eb shumic\u00ebs s\u00eb kontrolleve inkrementale n\u00eb vet\u00ebm pak sekonda. P\u00ebr ne kjo ishte nj\u00eb fitore e madhe.<\/p>\n<h2>Edhe m\u00eb shum\u00eb performanc\u00eb!<\/h2>\n<p>\nS\u00eb bashku me cache-in n\u00eb distanc\u00eb, p\u00ebr t\u00eb cilin fola m\u00eb sip\u00ebr, demoni mypy pothuajse i zgjidhi plot\u00ebsisht problemet q\u00eb shfaqeshin kur nj\u00eb programues e niste shpesh kontrollin e tipeve duke b\u00ebr\u00eb ndryshime vet\u00ebm n\u00eb pak skedar\u00eb. Megjithat\u00eb, performanca e sistemit n\u00eb skenarin m\u00eb pak t\u00eb favorsh\u00ebm t\u00eb p\u00ebrdorimit ende ishte larg optimalit. Nj\u00eb nisje e past\u00ebr e mypy mund t\u00eb zgjaste mbi 15 minuta. Kjo ishte shum\u00eb m\u00eb tep\u00ebr nga sa do t\u00eb na k\u00ebnaqte. \u00c7do jav\u00eb situata p\u00ebrkeq\u00ebsohej, pasi programuesit vazhdonin t\u00eb shkruanin kod t\u00eb ri dhe t\u00eb shtonin annotime n\u00eb kodin ekzistues. P\u00ebrdoruesit tan\u00eb ende k\u00ebrkonin m\u00eb shum\u00eb performanc\u00eb, dhe ne ishim t\u00eb gatsh\u00ebm t\u2019ua ofronim me k\u00ebnaq\u00ebsi.<\/p>\n<p>Vendos\u00ebm t\u2019i ktheheshim nj\u00eb prej ideve t\u00eb hershme p\u00ebr mypy: transformimit t\u00eb kodit Python n\u00eb kod C. Eksperimentet me Cython (nj\u00eb sistem q\u00eb lejon p\u00ebrkthimin e kodit t\u00eb shkruar n\u00eb Python n\u00eb kod C) nuk soll\u00ebn ndonj\u00eb p\u00ebrshpejtim t\u00eb duksh\u00ebm, ndaj vendos\u00ebm t\u00eb ringjallnim iden\u00eb e krijimit t\u00eb kompiluesit ton\u00eb. Meq\u00eb baza e kodit t\u00eb mypy (e shkruar n\u00eb Python) tashm\u00eb p\u00ebrmbante t\u00eb gjitha annotimet e nevojshme t\u00eb tipeve, na u duk me vler\u00eb t\u00eb provonim p\u00ebrdorimin e tyre p\u00ebr t\u00eb p\u00ebrshpejtuar sistemin. Shpejt krijova nj\u00eb prototip p\u00ebr ta testuar k\u00ebt\u00eb ide. Ai tregoi n\u00eb mikro-benchmark-e t\u00eb ndryshme nj\u00eb rritje t\u00eb performanc\u00ebs prej m\u00eb shum\u00eb se 10 her\u00eb. Ideja jon\u00eb ishte t\u00eb kompiloheshin modulet Python n\u00eb module C me an\u00eb t\u00eb Cython dhe q\u00eb annotimet e tipeve t\u00eb shnd\u00ebrroheshin n\u00eb kontrolle tipesh t\u00eb kryera gjat\u00eb ekzekutimit t\u00eb programit (zakonisht annotimet e tipeve shp\u00ebrfillen gjat\u00eb ekzekutimit dhe p\u00ebrdoren vet\u00ebm nga sistemet e kontrollit t\u00eb tipeve). N\u00eb thelb, po planifikonim ta kalonim implementimin e mypy nga Python n\u00eb nj\u00eb gjuh\u00eb q\u00eb ishte krijuar si statikisht e tipizuar, por q\u00eb do t\u00eb dukej (dhe, n\u00eb pjes\u00ebn m\u00eb t\u00eb madhe, do t\u00eb funksiononte) sakt\u00ebsisht si Python. (Kjo lloj migrimi nd\u00ebrmjet gjuh\u00ebve \u00ebsht\u00eb b\u00ebr\u00eb di\u00e7ka si tradit\u00eb p\u00ebr projektin mypy. Implementimi fillestar i mypy ishte shkruar n\u00eb Alore, nd\u00ebrsa m\u00eb pas pati nj\u00eb hibrid sintaksor t\u00eb Java dhe Python.)<\/p>\n<p>P\u00ebrqendrimi te API-ja e zgjerimeve t\u00eb CPython ishte \u00e7el\u00ebsi q\u00eb t\u00eb mos humbnim mund\u00ebsit\u00eb e menaxhimit t\u00eb projektit. Nuk na duhej t\u00eb implementonim nj\u00eb makin\u00eb virtuale apo \u00e7far\u00ebdo biblioteke q\u00eb i nevojitej mypy. P\u00ebr m\u00eb tep\u00ebr, e gjith\u00eb ekosistemi i Python do t\u00eb mbetej ende i disponuesh\u00ebm, po ashtu edhe t\u00eb gjitha mjetet p\u00ebrkat\u00ebse (si p.sh. pytest). Kjo do t\u00eb thoshte se gjat\u00eb zhvillimit mund t\u00eb vazhdonim t\u00eb p\u00ebrdornim kod Python t\u00eb interpretuar, gj\u00eb q\u00eb na lejonte t\u00eb ruanim nj\u00eb cik\u00ebl shum\u00eb t\u00eb shpejt\u00eb t\u00eb ndryshimeve n\u00eb kod dhe testimit t\u00eb tij, n\u00eb vend q\u00eb t\u00eb prisnim kompilimin. Dukej sikur po arrinim me sukses t\u00eb p\u00ebrfitonim nga t\u00eb dyja qasjet nj\u00ebkoh\u00ebsisht, dhe kjo na p\u00eblqente.<\/p>\n<p>Kompilatori q\u00eb e quajt\u00ebm mypyc (sepse p\u00ebrdor mypy si frontend p\u00ebr analiz\u00ebn e tipeve) doli t\u00eb ishte nj\u00eb projekt shum\u00eb i suksessh\u00ebm. N\u00eb p\u00ebrgjith\u00ebsi, arrit\u00ebm af\u00ebrsisht nj\u00eb p\u00ebrshpejtim 4 her\u00eb m\u00eb t\u00eb madh n\u00eb ekzekutimet e shpeshta t\u00eb mypy pa p\u00ebrdorur cache. Zhvillimi i b\u00ebrtham\u00ebs s\u00eb projektit mypyc i mori rreth 4 muaj kalendarik\u00eb nj\u00eb ekipi t\u00eb vog\u00ebl, ku b\u00ebnin pjes\u00eb Michael Sullivan, Ivan Levkivskyi, Hugh Han dhe un\u00eb. Ky v\u00ebllim pune ishte duksh\u00ebm m\u00eb i vog\u00ebl se ai q\u00eb do t\u00eb k\u00ebrkohej p\u00ebr ta rishkruar mypy, p\u00ebr shembull, n\u00eb C++ ose Go. Edhe ndryshimet q\u00eb na u desh t\u00eb b\u00ebnim n\u00eb projekt ishin shum\u00eb m\u00eb t\u00eb pakta se ato q\u00eb do t\u00eb nevojiteshin po t\u00eb rishkruhej n\u00eb nj\u00eb gjuh\u00eb tjet\u00ebr. P\u00ebrve\u00e7 k\u00ebsaj, shpresonim se do ta \u00e7onim mypyc n\u00eb nj\u00eb nivel t\u00eb till\u00eb q\u00eb programues t\u00eb tjer\u00eb n\u00eb Dropbox t\u00eb mund ta p\u00ebrdornin p\u00ebr t\u00eb kompiluar dhe p\u00ebrshpejtuar kodin e tyre.<\/p>\n<p>P\u00ebr t\u00eb arritur k\u00ebt\u00eb nivel performance, na u desh t\u00eb zbatonim disa zgjidhje interesante inxhinierike. P\u00ebr shembull, kompajleri mund t\u00eb p\u00ebrshpejtoj\u00eb ekzekutimin e shum\u00eb operacioneve duke p\u00ebrdorur konstruksione t\u00eb shpejta t\u00eb nivelit t\u00eb ul\u00ebt n\u00eb C. P\u00ebr shembull, thirrja e nj\u00eb funksioni t\u00eb kompiluar p\u00ebrkthehet n\u00eb nj\u00eb thirrje t\u00eb funksionit C. Dhe nj\u00eb thirrje e till\u00eb ekzekutohet shum\u00eb m\u00eb shpejt se thirrja e nj\u00eb funksioni t\u00eb interpretuar. Disa operacione, si k\u00ebrkimi n\u00eb fjalor\u00eb, ende reduktoheshin n\u00eb p\u00ebrdorimin e thirrjeve t\u00eb zakonshme t\u00eb C-API nga CPython, t\u00eb cilat pas kompilimit rezultonin vet\u00ebm pak m\u00eb t\u00eb shpejta. Arrit\u00ebm t\u00eb eliminonim ngarkes\u00ebn shtes\u00eb mbi sistemin t\u00eb krijuar nga interpretimi, por n\u00eb k\u00ebt\u00eb rast kjo solli vet\u00ebm nj\u00eb p\u00ebrfitim t\u00eb vog\u00ebl n\u00eb aspektin e performanc\u00ebs.<\/p>\n<p>P\u00ebr t\u00eb identifikuar operacionet \u201ct\u00eb ngadalta\u201d m\u00eb t\u00eb zakonshme, b\u00ebm\u00eb profilizimin e kodit. T\u00eb pajisur me t\u00eb dh\u00ebnat e marra, u p\u00ebrpoq\u00ebm ose ta p\u00ebrshtatnim mypyc n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb gjeneronte kod C m\u00eb t\u00eb shpejt\u00eb p\u00ebr operacione t\u00eb tilla, ose t\u00eb rishkruanim kodin p\u00ebrkat\u00ebs Python duke p\u00ebrdorur operacione m\u00eb t\u00eb shpejta (dhe ndonj\u00ebher\u00eb thjesht nuk kishim nj\u00eb zgjidhje mjaftuesh\u00ebm t\u00eb thjesht\u00eb p\u00ebr nj\u00eb problem t\u00eb caktuar). Rishkrimi i kodit Python shpesh rezultonte nj\u00eb zgjidhje m\u00eb e leht\u00eb sesa zbatimi i ekzekutimit automatik t\u00eb t\u00eb nj\u00ebjtit transformim n\u00eb kompajler. N\u00eb planin afatgjat\u00eb, donim t\u00eb automatizonim shum\u00eb prej k\u00ebtyre transformimeve, por n\u00eb at\u00eb moment synonim t\u00eb p\u00ebrshpejtonim mypy me sa m\u00eb pak p\u00ebrpjekje. Dhe, duke l\u00ebvizur drejt k\u00ebtij q\u00ebllimi, b\u00ebm\u00eb disa kompromise.<\/p>\n<p>To be continued...<\/p>\n<p><b>T\u00eb nderuar lexues!<\/b> \u00c7far\u00eb p\u00ebrshtypjesh ju la projekti mypy n\u00eb koh\u00ebn kur m\u00ebsuat p\u00ebr ekzistenc\u00ebn e tij?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve n\u00eb 4 milion\u00eb rreshta kodi Python. Pjesa 2\" src=\"\/wp-content\/uploads\/2019\/09\/e3c1dd40228b56d0196fd65e4df22a59.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Rruga drejt kontrollit t\u00eb tipeve n\u00eb 4 milion\u00eb rreshta kodi Python. Pjesa 2\" src=\"\/wp-content\/uploads\/2019\/09\/263173dd3ab487da330ff9063e3c180e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u2192 \u0427\u0438\u0442\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0442\u0438\u043f\u043e\u0432 (PEP 484) \u041c\u044b \u043f\u0440\u043e\u0432\u0435\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u0441 mypy \u0432 Dropbox \u0432\u043e \u0432\u0440\u0435\u043c\u044f Hack Week 2014. Hack Week \u2014 \u044d\u0442\u043e \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u0435, \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043c\u043e\u0435 Dropbox \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u043d\u0435\u0434\u0435\u043b\u0438. \u0412 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28879,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38479","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:23:56+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:23:56+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Rruga drejt kontrollit t\u00eb tipeve p\u00ebr 4 milion\u00eb rreshta kodi Python. Pjesa 2 | ProHoster","description":"Sot publikojm\u00eb pjes\u00ebn e dyt\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit mbi m\u00ebnyr\u00ebn se si Dropbox organizoi kontrollin e tipeve p\u00ebr disa miliona rreshta kodi Python.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster","og:description":"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:23:56+00:00","article:modified_time":"2019-10-31T19:23:56+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38479","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 22:13:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:08:32","updated":"2026-08-11 12:50:31","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=38479"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38479\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/28879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=38479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=38479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=38479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}