2010-04-23 2 views
35

Я просто наткнулся на Cython, пока я искал способы оптимизации кода Python. Я читал разные сообщения о stackoverflow, вики python и читал статью «Общие правила оптимизации».Cython Speed ​​Boost против юзабилити

Cython - это то, что больше всего меня интересует; вместо того, чтобы писать C-код для себя, вы можете выбрать другие типы данных в вашем коде python.

Вот глупый тест я попробовал,

#!/usr/bin/python 
# test.pyx 
def test(value): 
    for i in xrange(value): 
    i**2 
    if(i==1000000): 
     print i 

test(10000001) 

$ время питон test.pyx

real 0m16.774s 
user 0m16.745s 
sys  0m0.024s 

$ времени Cython test.pyx

real 0m0.513s 
user 0m0.196s 
sys  0m0.052s 

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

+14

Вы измеряете время выполнения скрипта Python и время компиляции некоторого кода Cython. Это не имеет никакого значения. –

+2

Что касается вашего последнего замечания: это в основном то, что пытается сделать Джулия: создание оптимизированного низкоуровневого транслятора кода на согласованном высокоуровневом машинном языке и четкое отображение этого намерения с самого начала, чтобы оно улучшалось, даже если оно означает, что некоторые функции высокого уровня теряются таким образом, как динамическая типизация. – gaborous

+1

@SturlaMolden: Разве это не тест интерпретации Python против Cython и не выполняется? Если это так, это имеет смысл. – Eddy

ответ

50

Другие ответы уже объяснили, как вы просто составляли код Cython, а не выполняли его. Тем не менее, я подумал, что вам может понадобиться узнать, насколько быстрее Cython может сделать ваш код. Когда я скомпилировал код, который у вас есть (хотя я запускал функцию из другого модуля) с distutils, я получил очень незначительную прирост скорости по сравнению с прямым Python - около 1%.Тем не менее, когда я добавил несколько небольших изменений в код:

def test(long long value): 
    cdef long long i 
    cdef long long z 
    for i in xrange(value): 
     z = i**2 
     if(i==1000000): 
      print i 
     if z < i: 
      print "yes" 

и скомпилированный его, я получил следующие времена:

  • Чистый код Python: +20,4553578737 секунд
  • Cython код : 0.199339860234 секунды

Это 100-кратное ускорение. Не слишком потертый.

+27

Возможно, это связано с ценой правильности. Код Python вычисляет правильное значение 'i ** 2'. C-код переполняется для большинства номеров, для которых вы выполняете операцию, если вы компилируете 32-разрядный код. (Если он вообще выполняет операцию. Возможно, ваш компилятор C полностью оптимизирует операцию). Это, вероятно, не справедливое сравнение. Вы также не полностью поняли, что вы используете, как вы его используете, и то, что вы выбираете, когда вы даете те времена. –

+0

Кстати, это то, что я имел в виду под «причудами». Я почти представил пример переполнения, как когда код Python автоматически выполняет проверки, которые обеспечивают правильность, и такие, которые не сработают молча в C. –

+6

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

18

Cython не является другим переводчиком. Он генерирует c-расширения для python, из кода python (-like). cython test.pyx будет генерировать только файл test.c, который (после компиляции) может использоваться python, как обычная библиотека python.

Это означает, что вы измеряете время, необходимое для того, чтобы cython переводил ваш код на python в c, а не как быстро выполнялась эта версия вашего кода.

+4

Да, для тех, кто хочет, чтобы этот cython действительно скомпилировал и запускал вашу программу в одной строке, я создал runcython (https://github.com/russell91/runcython). 'runcython test.pyx' будет иметь семантику, предназначенную для OP. – RussellStewart

9
  • cython test.pyx фактически не запускает вашу программу. Бинарный файл cython предназначен для обработки вашего кода Cython в модуль расширения Python. Вам нужно будет импортировать его в Python для его запуска.

  • #!/usr/bin/python не самая лучшая строка для скриптов Python. #!/usr/bin/env python, как правило, является предпочтительным, который запускается независимо от python в командной строке.

    • Cython pyx файлы, вероятно, не должны иметь притон линии на всех, за исключением угла случае, если они являются действительными программами Python.
  • У вас есть IndentationError в опубликованном коде.

  • Использование традиционного интерпретатора является более простым и портативным. Cython является надежным, но имеет свои ограничения и причуды. Возможно, было бы разумно использовать его больше, если это волшебным образом ускорило ваши тайминги, чтобы они выглядели так, как будто это действительно так, но на самом деле они дают меньшие. Вам нужно будет начать использовать Cython-специфические функции, чтобы использовать возможности C, чтобы видеть много ускорения.

9

Большая точка, которая, кажется, отсутствует: Cython не является строгим надмножеством Python. Есть некоторые функции, поддерживаемые Python, но Cython этого не делает. В первую очередь, генераторы и лямбды (но они идут).

+2

Знаете ли вы, пришли ли они еще? –

2
  • Самая большая причина, по которой Cython не так популярен в том, что ей не хватает автономных (без python) исполняемых файлов.

  • Отсутствие гласности. Разработчики, похоже, больше интересуются учеными в разработке своего Sage-программного обеспечения, чем передовой язык.

  • Ловушки встретились во время разработки. Я столкнулся с недостатком поддержки истинных потоков. Все обернуто в глобальную блокировку интерпретатора, делая его потокобезопасным, но отключая параллелизм!

+6

Вы можете освободить GIL, когда он не понадобится.То есть, когда вы не используете API Python C. В Cython это написано как «с nogil:», и вы получите сообщение об ошибке при выпуске GIL небезопасно. Потоки Python являются встроенными потоками ОС и будут давать вам параллелизм при выпуске GIL. Это верно для Python и Cython. –

+0

Согласно [wikipedia] (https://en.wikipedia.org/wiki/Global_interpreter_lock) CPython (т.е. Python) использует GIL, и поэтому его возможности параллелизма/параллелизма не лучше Cython's. –

2

Для тех, кто хочет что Cython на самом деле компилируется и побежал программу в одной строке, я создал runcython (http://github.com/russell91/runcython). runcython test.pyx будет иметь семантику, предназначенную для ОП