Bonjour, Habr!
Je veux vous parler d'un Ă©vĂ©nement incroyable que j'ai appris il y a quelques mois. Il s'avĂšre qu'un utilitaire python populaire est distribuĂ© depuis plus d'un an sous forme de binaires compilĂ©s directement Ă partir de python. Et il ne s'agit pas d'un empaquetage banal par certains PyInstaller , mais d'une compilation honnĂȘte Ahead-of-time de tout le paquet python. Si vous ĂȘtes aussi surpris que moi, bienvenue chez cat.
Laissez-moi vous expliquer pourquoi je pense que cet événement est vraiment incroyable. Il existe deux types de compilation: Ahead-of-time (AOT) , lorsque tout le code est compilé avant de démarrer le programme, et Just in time compiler (JIT) , lorsque le programme est directement compilé pour l'architecture de processeur requise lors de son exécution . Dans le second cas, le lancement initial du programme est effectué par une machine virtuelle ou un interpréteur.
Si nous regroupons les langages de programmation populaires par type de compilation, nous obtenons la liste suivante:
Compilateur en avance: C, C ++, Rust, Kotlin, Nim, D, Go, Dart;
Compilateur juste Ă temps: Lua, C #, Groovy, Dart.
Il n'y a pas de compilateur JIT prĂȘt Ă l'emploi en python, mais des bibliothĂšques sĂ©parĂ©es offrant une telle opportunitĂ© existent depuis longtemps
, : . : Kotlin JIT JavaVM, AOT Kotlin/Native. Dart ( 2). A JIT-, .
, , . .
JIT , . JIT . AOT , ? , .
, , . mypy - python-.
2019 , . â mypyc. , â 4 Python-â mypy ( : 1, 2, 3). mypyc: mypy python- Dropbox, , . , : go cython. â AOT python-.
, mypy , . mypy ââ python, , mypyc .
, , python-. Python c 3.4 , mypy . , python , AOT . , mypyc !
bubble_sort
ââ. lib.py:
def bubble_sort(data):
n = len(data)
for i in range(n - 1):
for j in range(n - i - 1):
if data[j] > data[j + 1]:
buff = data[j]
data[j] = data[j + 1]
data[j + 1] = buff
return data
, mypyc . , mypyc. , mypy, mypyc ! mypyc, :
> mypyc lib.py
:
.mypy_cache
â mypy , mypyc mypy AST;
build
â ;
lib.cpython-38-x86_64-linux-gnu.so
â . CPython Extension.
CPython Extension â CPython , /C++. , CPython lib. , python.
:
python ;
.so , mypyc gcc (gcc python-dev ).
lib.cpython-38-x86_64-linux-gnu.so
lib.py , .
. main.py :
import lib
data = lib.bubble_sort(list(range(5000, 0, -1)))
assert data == list(range(1, 5001))
:
|
|
|
real 5.68 user 5.60 sys 0.01 |
real 2.78 user 2.73 sys 0.01 |
(~ 2 ), , . .
â â, . , .
sum(a, b)
:
def sum(a, b):
return a + b
:
int sum(int a, int b) {
return a + b;
}
c ( ):
PyObject *CPyDef_sum(PyObject *cpy_r_a, PyObject *cpy_r_b){
return PyNumber_Add(cpy_r_a, cpy_r_b);
}
, . -, , PyObject, CPython . , , : , , , , . mypyc?
, : CPython . PyNumber_Add â Python, , Python .
CPython c Extension :
â - sum A, B;
â , , A + B;
â ;
â , - .
: , , .
, , , mypyc , .
sum(a: int, b: int)
, python, , , . , . , CPython - Extension. ?
, , , , CPython. mypyc , . mypyc , , sum. , , . , -, :
def sum(a: int, b: int):
return a + b
C ( ):
PyObject *CPyDef_sum(CPyTagged cpy_r_a, CPyTagged cpy_r_b) {
CPyTagged cpy_r_r0;
PyObject *cpy_r_r1;
cpy_r_r0 = CPyTagged_Add(cpy_r_a, cpy_r_b);
cpy_r_r1 = CPyTagged_StealAsObject(cpy_r_r0);
return cpy_r_r1;
}
, : , , . , .
CPyDef_sum PyObject, CPyTagged. int, CPython, mypyc, . , sum int .
CPyTaggetAdd PyNumber_Add. mypyc. CPyTaggetAdd, , a b, int, , :
if (likely(CPyTagged_CheckShort(left) && CPyTagged_CheckShort(right))) {
CPyTagged sum = left + right;
if (likely(!CPyTagged_IsAddOverflow(sum, left, right))) {
return sum;
}
}
, CPython - Extension :
â - sum A, B;
â , .
bubble_sort(data: List[int])
, . , data:
def bubble_sort(data: List[int]):
âŠ
:
|
, |
|
real 5.68 user 5.60 sys 0.01 |
real 2.78 user 2.73 sys 0.01 |
real 1.32 user 1.30 sys 0.01 |
, , , !
mypyc
, , . mypyc : , , , mypy. mypy . python-, , .
, , :
;
monkey patching;
Mypy , .
. , , abc. , . , gcc , , , . , , 20 % , .
Nuitka
, . Nuitka . , Nuitka Python ++ , Python Extension. , CPython libpython.
Nuitka , . mypy .
, mypy : , â â, PyCharm . , mypy. , . , python. mypy â , . , CPython , , . (, mypyc ). , mypyc , , , - , mypyc, , , mypy.
P.S.
, python, . , mypyc, , , .
UPD
, python - Cython, python ( cython-). cython , (real 1.82) mypyc . .