Найти - Пользователи
Полная версия: Cython оптимизация
Начало » Python для новичков » Cython оптимизация
1 2
alexx11
Если кто использует/использовал Cython, каких результатов в скорости удалось добиться в программе в целом, а не на участке кода?

Создатели этого языка утверждают об ускорении кода по сравнению с питоновским в 10-1000 раз. Но у меня сложилось субъективное мнение, что вызов ситоновских функций несколько замедляет процесс. Т.е. получив ускорение на 5-10% внутри функции, можно его лишиться при вызове. Но это значение столь невелико что однозначно утверждать это сложно.

Присутствуют так же функции которые выдерживают заявленную планку и ускоряются в 100 раз (в 1000 я что-то сомневаюсь). Хороший пример для этого trasnlit, или любая функция которая что-то делает в цикле со статическими данными.

Но в целом итог достаточно печальный. Привожу краткий отчёт своего эксперимента: скрипт ориентированный в основном для работы со строками. Был выбран один участок кода и полностью переведён в Cython. Я использовал для синхронизации препроцессор, поэтому по окончанию имеется одновременно код на двух языках. Т.е код алгоритмически идентичный. Это дало ускорение на 15%. После жёсткой инлайн оптимизации несколько тыщ строк (sick!), время выполнения сократилось ещё на 10%. Итого имеем 25%.

Что б до конца быть честным, скажу что за неделю эксперимента, программа потерпела серьёзные изменения в архитектуре, и тот же код на том же питоне стал работать в почти 5 раз быстрей.

P.S. Добавлю ещё то что скрипт на момент лучшей оптимизации работает на 90% с памятью и только 10% операции с файлами и БД.
Андрей Светлов
У меня были подобные задачи.

Переводить весь код “строчка в строчку” - нельзя.
Следует думать примерно так:
- что можно вынести в C Extension. Выносимый код должен быть тесно связан внутри и использовать минимум вызовов Python C API.
- перевод всего кода в Cython похож на разворачивание вызовов API не из ceval.c а из вашего генерируемого С кода. Выигрыша, действительно, почти нет.
Избавляетесь от работы по python bytecode, взамен (при использовании cpdef) получаете ожидаемое пенальти.
- cython всего лишь удобное средство писать C Extensions. Вы вносите в код многочисленные cdef типы, проверяете вывод cython -a <file.pyx> и смотрите на результирующий .c
- это нелегко и хорошая оптимизация требует знания C и комфортного понимания Python C API.
- на каждом работающем этапе сравниваете результаты бенчмарков (профайлер тоже хорошо помогает).
- после того, как ваш преобразованный код стал большей частью делать С вызовы и лишь в необходимых случаях использовать Python C API вы (возможно) увидите значимый прирост производительности.

Резюме.
Перед началом использования Cython следует представить, как бы ваш питоновский модуль мог бы выглядеть в виде Python C Extension.
Писать C Extension нелегко, один подсчет ссылок может свести с ума (но тем не менее это делают на plain C, поверьте).
Есть другие альтернативы, концентрирующиеся в основном на использовании С++ - boost::python лучшая из них на мой вкус.
Если вы все же выбрали Cython (для чего есть масса объективных причин) - будьте готовы, что вам придется пройти через чтение С кода очень много раз прежде чем получите значимое ускорение системы в целом.
alexx11
Андрей Светлов
Переводить весь код “строчка в строчку” - нельзя.
Я тоже начинаю это понимать, но как же тогда делать???
Андрей Светлов
Выносимый код должен быть тесно связан внутри и использовать минимум вызовов Python C API.
Это я и сделал: весь инлайн код обязан содержать только cython-объекты, в остальных функциях объявил всё что только можно, а именно без объявлений остались file и database -объекты. Т.е. это не просто переименование *.py в *.pyx =)
Андрей Светлов
Избавляетесь от работы по python bytecode, взамен (при использовании cpdef) получаете ожидаемое пенальти.
cpdef - не использовал, только def и cdef inline - для функций, для всего остального - cdef.
Андрей Светлов
смотрите на результирующий .c
Смотреть-то можно а вот что там можно увидеть, на питон пришёл как раз из си, пусть не прямыми путями, но детально разбирать машинный (генерённый) код задача не из простых, а закономерности, которые там можно наблюдать есть в доках. Для себя я в этом плане различаю только py- и pyx- обекты, и делаю выводы о сложности вызове функций.

Собственно впечатление, что всё что можно я сделал: комп три раза перезагрузил, монитор протёр, клаву почистил… ;) Может действительно что-то не учёл, и есть надежда что кто-нибудь или что-нибудь ещё сможет меня разубедить. Я это связываю в первую очередь с pgcc или с мультипроцессорной конфигурацией машины.
Андрей Светлов
Да нет никаких чудес!
Научитесь писать .so на чистом С - и увидите, как можно (и нельзя) оптимизировать код на Cython.
alexx11
Андрей Светлов
Научитесь писать .so на чистом С
Ахахаха, я постараюсь обойтись без написания библиотек на чистом си, хотя… нет, пожалуй точно нет.
Андрей Светлов
и увидите, как можно (и нельзя) оптимизировать код на Cython
Я конечно не исключаю что я настолько слеп что не вижу того “что не вижу”. Или всё таки “Да нет никаких чудес!” (с)
Андрей Светлов
И все таки, не видя вашего кода…
Могу предположить, что Cython поделку транслирует в не самый оптимальный вариант. И пока вы не научитесь свободно читать эту дикую и страшную простыню - толку не будет никакого.
Равно как и, гмм, от используемого вами препроцессора.
Писать не нужно (я сам в последний раз писал на ассемблере лет десять назад, к примеру). Читать следует научиться.
alexx11
Андрей Светлов
И все таки, не видя вашего кода…
А что мой код даст? Там всё в порядке. Он переоптимизирован настолько, что Cython из него выдаёт жалкие 25%.
Андрей Светлов
Писать не нужно (я сам в последний раз писал на ассемблере лет десять назад, к примеру). Читать следует научиться.
Дык а что более нужного чем различие py и pyx -обектов я не прочёл в этой простыне, ты уж поконкретней тогда.
Андрей Светлов
Равно как и, гмм, от используемого вами препроцессора.
Во-первых это синхронизация кода, т.е. я могу мгновенно отлаживать на питоне и собирать проект в ситоне, при этом менять архитектуру программы, удалять и добавлять новые типы. Освоив этот механизм мне кажется немыслимым иначе. Если конечно речь не идёт о об одной функции или модуле.
Во-вторых, именно с его помощью можно проводить чистые тесты. Т.е я уже писал выше что скорость выполнения программы с момента начала оптимизации выросла в 5 раз (это не выходя за рамки питона), но эту заслугу я не приписываю к ситону, как это могут сделать те, кто препроцессор не использует. Т.е я не нарушаю чистоту эксперимента.

И именно эти результаты опустили меня на землю, что чудес просто так не бывает. А что б код работал быстрей в 10 раз надо в 10+ раз больше процессоров, да и подход соответствующий. А эти процессоры, как можно почитать в интернетах, когда их больше одного, отказываются, паразиты, работать когда пользователь запускает свой скрипт xD.

Ладно отвлёкся, насчёт ситона, для меня это открытый вопрос, использовать его или нет, но в дальнейшем написании кода я его как-раз поддерживать с препроцессором буду, а что дальше посмотрим.
o7412369815963
alexx11, раз уж дело пошло на эксперименты, попробуйте из python'a выкусить критическую часть и написать её на C Extension. И вполне возможно производительность будет ещё выше чем на Cython.
alexx11
o7412369815963
попробуйте из python'a выкусить критическую часть и написать её на C Extension
Дело в том что это всё и есть узкое место - это такой большой один цикл, которой за счёт методов инлайн подстановок выглядит практически линейно. Т.е я хочу сказать что замена сотни строк питон-кода, даже самого критического, и даже на мгновенное исполнение, не даст общего улучшения даже на 5%.

Другое дело что ситон все операции со строками сложнее проверки типов или сравнения выполняет стандартынми питоновским библиотеками, даже своего поиска подстроки нет! И узкое место моего скрипта, это, можно сказать, нормальная библиотечка работы со строками в ситоне :]
Андрей Светлов
Может и так - но, думается, стоит еще поискать.
Как-то в финансовом софте профайлер показывал, что 50% времени тратится на работу со строками.
Думаете, эти операции нужно было ускорять?
Нет, их просто требовалось выкинуть. Заменив на более адекватные структуры данных.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB