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

Опубликовано lamazavr - вс, 02/08/2015 - 13:41
Body

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...

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

Tags

Добавить комментарий

Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.