solovyov.net

Оптимизация в питоне

in python, programming by Alexander Solovyov

Есть тут у нас на сервере скрипт, который занимается относительно простым с виду делом — выводит в том формате, котором нам хочется, файлики в определённом каталоге. Ну чтоб качать их можно было. Написан был мной и Саней еще в марте, просто чтобы иметь возможность гибко управлять выводом — никакие реализации автоиндексов в различных веб-серверах никакой такой гибкости не обеспечивают. Ну написали — и он лежал себе, работал. Но вот несколько дней назад я окончательно разобрался с nginx'ом, сделал пару интересных штук, и понял, что и как нужно улучшить в скрипте. ;) Ну, нашёл его версию, работающую в FastCGI, всё завёл, запустили — и впустили на него реальных юзеров. ЛА поднялось до 3-4, а top писал, что питон отжирает 20-25% проца. Ну да, в принципе понятно — туда добавилось достаточно много функций, а также работа с БД — он имел право на более долгое исполнение... но не на торможение всей системы!

В общем, юзеров спихнули обратно, и я пошёл разбираться — первым делом отыскал советы по оптимизации, и начал их читать. Поубирал конкатенацию строк с помощью +, сделал всё через списки и .join.

В итоге — время исполнения скрипта на вывод одной из директорий (в которой много файлов) занимал целую секунду. Путём оптимизации с этой конкатенацией время стало 8 десятых — в принципе, 20% производительности — это неплохо... Но я просто задницей чуял где-то подвох. ;) И я таки нашёл его: взял и закомментировал функцию определения типа файла (да, эти самые image/jpeg и text/plain). Результат меня просто поразил: время исполнения снизилось до 3-5 сотых секунды! То есть практически в 20 раз...

Ну и на радостях я побежал смотреть другие директории: в корне оказалось 15 сотых, а вот в том месте, где было полтора десятка каталогов, время возросло (вот сейчас уже не уверен в точности чисел, лишь в их порядке) где-то до 45-60 сотых. Поразмышляв, я понял, что наверное просто сильно тормозят вызовы функции определения размера директории — а она у нас злая, определяет размер директории, пробегаясь по ней рекурсивно. Ну и, понятное дело, я решил переделать, чтоб эту функцию нужно было вызывать только 1 раз — а почитав те самые советы, убедился в этом. Переделал функцию так, что на входе получает список директорий, а на выходе отдаёт словарь с размерами — и время исполнения понизилось до 15 сотых. ;)

Вот так красиво скрипт ускорился во много раз. ;)

Все замечания и вопросы можно отправлять письмами на