SVEUČILIŠTE U ZAGREBU

PRIRODOSLOVNO – MATEMATIČKI FAKULTET

SEMINARSKI RAD PROJEKT „NUITKA“

Lucija Brleković

Zagreb, svibanj 2014.

1

Uvod

Pod implementacije Python-a podrazumijevaju se programi ili okoliši koji pružaju potporu izvršavanju programa pisanih u Python okruženju. Postoje različiti paketi koji omogućuju prepoznavanje različitih vrsta koda iz Pythona, neki su varijante ili modifikacije već postojećih dok su ostali napravljeni kao potpuno nove implementacije Python jezika. Npr. postoji čitav niz reimplementacija Pythona koji ne ovise nužno o CPython runtime jezgri. Većina njih koristi dijelove standardne knjižnice funkcija. TakoĎer je bitno za napomenuti da je većina njih još uvijek u stanju razvoja. Jedine implementacije koji su kompatibilne sa sadašnjom verzijom Python jezika su IronPython, i PyPy. MeĎu različitim varijantama implementacije nalazimo i čitav niz compiler-a koji obično implementiraju nešto slično Pythonu, iako neki od njih nameću odreĎena ograničenja ali ne nužno. Neki od njih su: Cython (koristi se za optimizaciju pretvorbe Python koda u compiler kod, i sl.), GCC Python Front-End (projekt koji je još uvijek u tijeku, compiler Python koda unutar GCC infrastrukture), Shed Skin (Python-to-C++ compiler, ograničen samo na neke komponente jezika) i Nuitka. Nuitka je Python-to-C++ compiler koji koristi libpython u run-time-u, u svrhu optimizacije, takoĎer koristi i CPython runtime.

1

Nuitka – Python – C++ Compiler

Nuitka je nastala kao samostalni projekt informatičara K. Haye koji se bavi projektima na polju informacijsko komunikacijskih tehnologija. Uz ovo polje se vežu mnoge primjene Python programskom jezika. Pyhton se koristi ne samo kao alat za upravljanje procesima, nego i kao sigurnosni alat kojim se nadziru neki kritični procesi sustava. Ciljevi razvoja Nuitke – Python Compiler-a su vezani uz:

- povećanje brzine izvršavanja programa bez uvoĎenja novih naredbi,

- uklanjanje jezičnih prepreka izmeĎu Python-a i C++-a,

- korištenje standardne dijagnostike pogrešaka (error messaging),

- osiguravanje kompatibilnosti sa već postojećim modulima unutar Python-a.

Alternativni alati

Alternativni alati slični Nuitka-i su: PyPy/RPython (jezik ograničen samo na dijelove funkcionalnosti), PyPy/JIT (vezano uz JIT), PyRex/Cython (drugačiji jezik od Pythona – nekompatibilnost sa postojećim Python standardima). Pošto Nuitka spada u skupinu Python-C++ compiler-a bitno je naglasiti odreĎene različitosti izmeĎu spomenutih jezika, kao i neke funkcionalne različitosti koje predstavljaju prepreke pretvorbi samog koda. Problematične razlike izmeĎu C++ i Python jezika:

- analogija operatora OR i AND (&& i ||) postoji, ali nije odgovarajuća u smislu da se može iskoristiti na valjan način.

- u C++ programskoj paradigmi ne postoje oblici tipa try ... finally,

- različitosti u evaluacija pozivnih argumenata funkcija,

- rad sa stringovima.

Potrebno je uzeti u obzir i način na koji se ove različitosti mogu zaobići. Jedno rješenje bi bilo da se specijalne jezične konstrukcije pišu u odvojene file-ove, što zapravo ne bi predstavljalo poboljšanje, a osobito ne u slučajevima kada su bitne performanse – brzina samog izvoĎenja i prevoĎenja programa. 2

Nuitka – ciljevi i motivacija

Ciljeva razvoja Nuitka projekta Python Compilera vezani su uz poboljšanje svojstava pisanog koda, kako brzine tako i čitljivosti, meĎuostalim i:

- ukloniti prepreke uporabi konstanti kao globalnih varijabli, što se dosad izbjegavalo radi sporijeg izvoĎenja samog koda,

- pozivanje fukcija unutar koda mora biti u čitljivom obliku,

- izvještavanje vezano uz vrijeme kompilacije – ako se koristi varijabla kojoj nije pridijeljena vrijednost pogreške i upozorenja se u standardnom Python-u javljaju prekasno, što rezultira duljim vremenom razvoja samih programa.

- povezivanje sa već razvijenim funkcionalnostima - uloga PyLint-a u daljnjem razvoju Niutke,

- uklanjanje ograničenja na mogućnosti compiler-a – sve funkcionalnost koju je moguće ostvariti u Python-u mora biti dostupna i u Nuitka-i.

- standardne poruke vezane uz izvještavanje o pogreškama (greške u sintaksi, greške u pretvorbi ili načinu korištenja odreĎenog tipa podataka, pogreške prilikom pozivanja funkcija, itd.) moraju biti zadržane.

Jedna od različitosti spomenuta dva programska jezika su i definirani tipovi podataka koji se mogu koristiti. Anotacije tipova u odvojenom file-u bi ujedno uključivale i sljedeće:

- ovo rješenje bi bilo efektivno samo u slučajevima kad se program izvršava korištenjem compiler-a,

- izrazi oblika „must be an integer“ su važne informacije. Općenito poboljšavaju kvalitetu koda i često se pojavljuju kao „assertions“ i kao takve ne bi trebali biti sadržani u eksternalnom file-u,

- održavanje dva ili više file-ova umjesto jednog takoĎer uvodi dodatne poteškoće, kako za razvoj tako i za kompleksnost same strukture.

3

MeĎu ciljevima koji se žele postići je i zadržavanje već postojeće Python sintakse, stoga se izbjegava uvoĎenje nove sintakse. Nova sintaksa, odnosno novi jezik ujedno znači i ogroman gubitak funkcionalnosti, neki od problema koje nova sintaksa donosi su:

- IDE Auto Completition alati (alati za prepoznavanje sintakse npr. Emacs),

- IDE aliati za označavanje sintakse,

- PyLint provjere (PyLint se koristi za provjeru usklaĎenosti koda sa Python standardima, provjere duljine koda, provjere varijabli, provjere modula korištenih unutar koda, detekcija pogrešaka, i sl.),

- grafovi ovisnosti (koriste se za prikaz ovisnosti objekata unutar strukture koda),

- nepostojanje sučelja prema već razvijenim Python alatima (Cpython, Jython, PyPy, itd.).

Sve devijacije od standardnih alata ujedno bi značile i gubitak funkcionalnosti, odnosno uključivale bi definiranje novih sučelja prema već postojećim alatima što dodatno komplicira situaciju. Kratak pregled glavnih ideja projekta Nuitka

Nuitka je orijentirana prema pronalasku rješenja koja ne povlače za sobom uvoĎenje nove sintakse, nego korištenje već postojeće sintakse u svrhu uklanjanja razlika. Kao primjer se može dati iduća naredba (Nuitka):

X=hints.mustbeint(x)

Compiler prepoznaje hints kao odvojen module, koji sadrži funkciju mustbeint, a x može u C++ okruženju postati ili int x ili PyObjectorInt.

meters_per_nautical_mile = 1852

def convertMetersToNauticalMiles ( meters ): 4

return meters / meters_per_nautical mile

def convertNauticalMilesToMeters ( miles ):

return miles * meters_per_nautical mile

def convertMetersToNauticalMiles ( meters ):

return meters / 1852

def convertNauticalMilesToMeters ( miles ):

return miles * 1852

Odsječak Python koda se izvršava sporije zbog definiranja dodatnih globalnih varijabli, gore u kodu, u ovom slučaju riječ je o konstanti meters_per_nautical_mile. Izbacivanjem globalne varijable (takoĎer prikazano u gornjoj tablici) gubi se čitljivost koda. Ako bi se željela postići još veća brzina izvoĎenja koda bilo bi potrebno u potpunosti ukloniti obje funkcije i pretvorbu iz metara u nautičke milje vršiti u samom kodu (bez korištenja funkcije). Velike prepreke brzini izvoĎenja predstavljaju i funkcije sljedećeg oblika:

def someFunction ( ):

len = len

# varijabla len

Predefiniranje globalnih varijabli u lokalni namespace nužno rezultira smanjenom čitljivosti koda. Ali bez toga len() se poziva mnogo sporije. Compiler mora pretražiti sve module u kojima se nalazi definicija varijable što značajno usporava izvršavanje koda.

return Generator.getFcuntionCallCode (

function_identifier =Function_identifier,

5

argument_tuple = Argument_tuple,

argument_dictionary= Argument_dictionary,

star_list_identifier = Star_list_identifier,

star_dict_identifier = Star_dict_identifier,

)

return Generator.getFcuntionCallCode (

function_identifier, argument_tuple, argument_dictionary, star_list_identifier ...

)

Korištenje keyword (ključne riječi) argumenata je takoĎer neefikasno rješenje za opisani problem. Proces se sada sastoji od sljedećeg: prilikom svakog poziva funkcije stvara se novi direktorij koji se koristi za naredne korake, pozvana funkcija mora testirati ime svakog argumenta funkcije, svih mogućih dodatnih argumenata, izvršiti provjeru tipova argumenata, itd. Svaki parametar se mora naći u dictionary-u što takoĎer značajno produljuje vrijeme izvršavanja koda. Jedan od primjera optimizacije Python koda je CPython.

Optimizacija performansi u Cpythonu rezultira sljedećim:

- smanjena čitljivost koda,

- gori dizajn nego što je nužno, narušena struktura koda.

Nuitka – optimizacija koda

Optimizacija koja se želi postići tiče se i izvornog koda u smislu da programer koji razvija kod ne mora koristiti ograničenja na tipove podataka ako je to vidljivo već iz samog koda. Nema potrebe za operacijama tipa ručno uvlačenje dijelova koda, kopiranje identifikatora u lokalni scope, itd. Svi postojeći alternativni alati imaju

6

odreĎene prednosti, ali zbog svojih manjkavosti ne predstavljaju cjelokupno rješenje problematike. Potreba za približavanjem C++-a i Python Compiler-a je više nego nužna. Neke od različitosti koje predstavljaju prepreku ovome su:

 rad sa logičkim operatorima (već spomenuto),

 u C++-u ne postoji funkcionalnost vezanih usporedbi kao u Python-u ( f()

 evaluacija izraza,

 try..finally konstrukcija (sadašnja verzija Nuitke omogućuje ovu funkcionalnost),

 C++ naredbe break i continue nemaju odgovarajuće analogije u Python-u,

 način pozivanja funkcija, evaluacija argumenata funkcije puno je jasnija i jednostavnija nego odgovarajuća u C++-u. Postoje odreĎene različitosti i meĎu C++ Compilerima (ARM, Intel, ...),

 način rada sa string varijablama, Python raw_strings posjeduje čitavo bogatstvo funkcija i mogućnosti dok je odgovarajuća funkcionalnost u C++-u manjkava ili funkcionalno ograničena.

Konačni ciljevi projekta Nuitka su sljedeći:

 uključiti korisne, već postojeće funkcionalnosti iz CPythona,

 generirati efikasan C++ kod korištenjem PyObject implementacija i postići veću brzinu izvršavanja,

 propagacija imenovanih konstanti – identificirati što je moguće više vrijednosti i ograničenja za vrijeme kompilacije u cilju povećanja efikasnosti koda,

 uvoĎenje tipa „Interface“ – detektirati specijalne slučajeve (situacije u kojima do izražaja dolaze različitosti Python-a i C++-a) u programu (tipovi str,int,list),

 sučelje prema C kodu – Nuitka bi trebala prepoznati i shvatiti ctype i cffi povezivanja.

7

 modul „hints“ – alat koji developeru pruža dodatne mogućnosti vezane uz informativnost, razumljivost i čitljivost koda.

Svi ciljevi vode ka ubrzanju i optimizaciji izvršavanja koda. Nuitka je zasad ograničena na:

- Linux x86/64,

- Linux ARM,

- Windows – MinGW.

Preduvjeti za instalacije Nuitke su:

- Python 2.6 ili 2.7, 3.2 eksperimentalno

- g++ 4.5, g++4.6, g++4.7 ili 3.0.

Zaključak

Nuitka je Python-to-C++ compiler koji koristi libpython u run-time-u, u svrhu optimizacije, takoĎer koristi i CPython runtime. Konačni ciljevi projekta Nuitka su sljedeći: uključiti korisne, već postojeće funkcionalnosti iz CPythona, generirati efikasan C++ kod korištenjem PyObject implementacija i postići veću brzinu izvršavanja, propagacija imenovanih konstanti, detektirati specijalne slučajeve u programu, sučelje prema C kodu. Svi ciljevi vode ka ubrzanju i optimizaciji izvršavanja koda. Nuitka je zasad ograničena na: Linux x86/64, Linux ARM, Windows – MinGW. Da bi Nuitka u potpunosti bila funkcionalna treba još puno raditi na njenom razvoju.

8

Pregled literature i dostupnih materijala

- https://www.youtube.com/watch?v=ZDHkla5rllg (predavanje tvorca Nuitke dostupno na Web stranici, K. Haye, 4. 5.2012., EuroPython); [08.05.2014.]

- http://nuitka.net/doc/user-manual.html (Nuitka User Manual - opis osnovnih mogućnosti i ideja projekta, sintaksa, objašnjenja i reprezentativni primjeri); [08.05.2014.]

- http://nuitka.net/doc/developer-manual.html (Nuitka Developer Manual - opis ciljeva i procjene ostvarenoga, priručnik za sve Python programere koji djeluju unutar samog projekta Nuitka); [08.05.2014.]

- https://zvzzt.wordpress.com/2012/09/05/nuitka-python-compiled-to-c- potentially-faster-than-gnu-stdlib-c-libraries-and-boost/ (primjer korištenja Nuitke, pregled ostvarenog unutar samog projekta); [08.05.2014.]

- https://groups.google.com/forum/#!topic/python-static-type- checking/cikr8Ev5dGs (Google grupa - forum na temu Nuika); [08.05.2014.]

- http://www.verious.com/source/nuitka-home-and-blog-of-kay-hayen/ (Nuitka blog); [08.05.2014.]

- http://labs.stephenou.com/hn/item/6428387 (Hacker News forum na temu Nuitka); [08.05.2014.]

9