Cython - python приложение на C

Сообщение об ошибке

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls в функции menu_set_active_trail() (строка 2405 в файле /home/ih139182/public_html/includes/menu.inc).

Cython - это язык программирования, который дополняет python возможностью типизированного задания переменных и возможностью компиляции в Си код, который в последствии можно скомпилировать в бинарник.
Python потрясающий язык программирования. Но скорость его выполнения оставляет желать лучшего. И как раз в этом нам может помоч cython. На данный момент он практически без труда умеет компилировать python код в си.

Давайте рассмотрим все на примере.
Вот код python для нахождения чисел Фибаначи.

def fib(n):
	if n==0:
		return 0
	elif n==1:
		return 1
	else:
		return fib(n-1) + fib(n-2)
		
		
result = []
for i in range (30):
	result.append(fib(i))
print result

Ничего сложного. Быстро и удобно. Но сколько времени занимает выполнение?

$ time python fib.py 
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]

real	0m0.933s
user	0m0.926s
sys	0m0.008s

А теперь рассмотрим тот же код cython.

cdef fib(int n):
	if n==0:
		return 0
	elif n==1:
		return 1
	else:
		return fib(n-1) + fib(n-2)
		
		
result = []
for i in range (30):
	result.append(fib(i))
print result

Тот же код, только cdef вместо def и параметр, который передается в функцию помечен как целочисленный.
Скомпилируем этот код в си.

cython -2 --embed fib.pyx -o fib.c

embed - говорит компилятору, генерировать так же код main функции.

Теперь компилируем полученный файл при помощи gcc.

gcc fib.c -o fib `python-config --includes --ldflags`

Запускаем.

$ time ./fib 
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]

real	0m0.135s
user	0m0.128s
sys	0m0.007s

Как видите, резульат - всем результатам результат!

Кроме того, можно скомпилировать cython модуль в разделяемую библиотеку и импортировать её в интерпритатор python.
Создадим функцию.

def helloFunction ():
    return 'Hello World!'

Компилируем.

cython -2 mycode.pyx -o mycode.c
gcc -g -O2 -shared -o mycode.so mycode.c `python-config --includes --ldflags` -fPIC

Запускаем интерпритатор и пробуем выполнить.

$ python
Python 2.7.8 (default, Nov 10 2014, 08:19:18) 
[GCC 4.9.2 20141101 (Red Hat 4.9.2-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mycode
>>> mycode.helloFunction()
'Hello World!'

А теперь наоборот! Выполняем функцию из C кода.
Создаем файл pyapp.pyx.

def helloFunction():
	return "Hello world!"

cdef public void start_app():
	print helloFunction()

Компилируем.

cython pyapp.pyx -o pyapp.c

Создаем файл main.c

#include <Python.h>
#include "pyapp.h"

int main (int argc, char **argv) 
{
	printf ("Initializing Python Runtime...\n");
	Py_Initialize ();

	/* инициализация нашего приложения */
	initpyapp();
	/* запускаем функцию */
	start_app();

	printf ("Cleanup...\n");
	Py_Finalize ();
	return 0;
}

Компилируем.

gcc -o app main.c pyapp.c `python-config --includes --ldflags`

Запускаем.

$ ./app 
Initializing Python Runtime...
Hello world!
Cleanup...

Сработало. Вот это да.

Просмотров:   5489