Есть тут у нас на сервере скрипт, который занимается относительно простым с виду делом - выводит в том формате, котором нам хочется, файлики в определённом каталоге. Ну чтоб качать их можно было. Написан был мной и Саней еще в марте, просто чтобы иметь возможность гибко управлять выводом - никакие реализации автоиндексов в различных веб-серверах никакой такой гибкости не обеспечивают. Ну написали - и он лежал себе, работал. Но вот несколько дней назад я окончательно разобрался с nginx’ом, сделал пару интересных штук, и понял, что и как нужно улучшить в скрипте. ;) Ну, нашёл его версию, работающую в FastCGI, всё завёл, запустили - и впустили на него реальных юзеров. ЛА поднялось до 3-4, а top писал, что питон отжирает 20-25% проца. Ну да, в принципе понятно - туда добавилось достаточно много функций, а также работа с БД - он имел право на более долгое исполнение… но не на торможение всей системы!
В общем, юзеров спихнули обратно, и я пошёл разбираться - первым делом отыскал советы по оптимизации, и начал их читать. Поубирал конкатенацию строк с помощью +, сделал всё через списки и .join.
В итоге - время исполнения скрипта на вывод одной из директорий (в которой много файлов) занимал целую секунду. Путём оптимизации с этой конкатенацией время стало 8 десятых - в принципе, 20% производительности - это неплохо… Но я просто задницей чуял где-то подвох. ;) И я таки нашёл его: взял и закомментировал функцию определения типа файла (да, эти самые image/jpeg и text/plain). Результат меня просто поразил: время исполнения снизилось до 3-5 сотых секунды! То есть практически в 20 раз…
Ну и на радостях я побежал смотреть другие директории: в корне оказалось 15 сотых, а вот в том месте, где было полтора десятка каталогов, время возросло (вот сейчас уже не уверен в точности чисел, лишь в их порядке) где-то до 45-60 сотых. Поразмышляв, я понял, что наверное просто сильно тормозят вызовы функции определения размера директории - а она у нас злая, определяет размер директории, пробегаясь по ней рекурсивно. Ну и, понятное дело, я решил переделать, чтоб эту функцию нужно было вызывать только 1 раз - а почитав те самые советы, убедился в этом. Переделал функцию так, что на входе получает список директорий, а на выходе отдаёт словарь с размерами - и время исполнения понизилось до 15 сотых. ;)
Вот так красиво скрипт ускорился во много раз. ;)