Как стать автором
Обновить

Комментарии 6

А насколько Cython совместим с библиотеками и с модулями, или где приведен перечень, которые работают с Cython? Меня интересует работа с jaydebeapi, os и glob.

Полная совместимость. Результат работы Cython - это pyd, бинарные модули Python. Грубо говоря виртуальной машине Python без разницы выполняет ли она скрипт, или бинарный модуль.

В качестве альтернативы можно посмотреть на транслятор обычного Питона (а не новый язык как в случае Cython) в Си: github.com/Nuitka/Nuitka
Без каких-то особых проблем на нем даже смог скомпилировать такой крупный проект как youtube-dl !

Есть такой код на Python (который считает k-ое по счёту простое число для k = 1 000 000).
Скрытый текст
import math

def prime():
    k = 1000000
    n = k * 17
    primes = [True] * n
    primes[0] = primes[1] = False

    for i in range(2, int(math.sqrt(n)) + 1):
        if not primes[i]:
            continue
        for j in range(i * i, n, i):
            primes[j] = False

    for i in range(n):
        if primes[i]:
            if k == 1:
                return i
            k -= 1

print(prime())


Я попытался переписать его под Cython.
Скрытый текст
import math
from libc.stdlib cimport malloc, free

def prime():
    cdef int k = 1000000
    cdef int n = k * 17
    cdef bint *primes = <bint *>malloc(17000000 * sizeof(bint))
    cdef int i, j
    for i in range(17000000):
        primes[i] = True
    primes[0] = False
    primes[1] = False

    for i in range(2, int(math.sqrt(n)) + 1):
        if not primes[i]:
            continue
        for j in range(i * i, n, i):
            primes[j] = False

    for i in range(n):
        if primes[i]:
            if k == 1:
                free(primes)
                return i
            k -= 1


В результате получилось всего лишь в 5 раз быстрее.
Что не так в приведённом Cython-коде?

(Для сравнения: оригинальный Python-код [вообще без каких-либо изменений] ускоряется посредством траспайлера Python → 11l → C++ почти в 20 раз, что сопоставимо по скорости с реализацией на C/C++.)

Возможно в С-коде остается еще много вызовов к Питоновскому интерпретатору. Тот же math.sqrt через Питон вызывается, хотя здесь лучше взять его аналог из libc.

Можно переписать функцию, чтобы гененировался чистый Сшный код добавив спецификацию nogil. Тогда должно быть побыстрее.

def prime() nogil:

Для указанной задачки с определением простоты Numba должна быть плюс-минус сравнима по скорости с Cython. Вероятнее всего, дело в "непрогретости" (один из постов про это).

Вариант лечения: в декораторе после numba.njit уточнить в скобочках сигнатуру: (boolean(int_))

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации