В этой статье мы поговорим о некоторых аспектах, которые иногда упускают из виду разработчики и которые влияют на общую производительность веб-приложения.
В частности, мы рассмотрим, как влияют на производительность множественные подключения внешних файлов, наличие «мертвого» кода, ускорение через кэши опкодов и FastCGI для PHP. В какой-то степени статья является следствием темы «Хранение кода в базе данных или сбор кода по кирпичикам» , так как именно после него возникли множественные вопросы по производительности (кстати, его запустили не так давно другой проект построен на указанной технологии хранения всего кода в базе данных).
Одним из преимуществ рассмотренного подхода стала возможность получения на выходе чистого монолитного кода, не содержащего «мертвых» участков и подключений внешних файлов (например, через включать или требовать .
Ниже для простоты мы будем называть это просто «включает»).
Для тех, кто не знаком с этой темой, поясню, что «мертвый» — это код, который заведомо не будет выполняться на странице.
Немного науки.Как было сказано, чистый монолитный код существенно повышает общую производительность приложения, что вызвало массу споров и подозрений в комментариях.Вот что говорит о мертвом коде директор Института системотехники РАН, член-корреспондент РАН, один авторитетный парень Виктор Иванников: «Мертвый код — это часть программы или электрической схемы, которая никогда не исполняется, ни при каких условиях, ни при каких входных данных.
Это существенная проблема, особенно для систем с ограниченной памятью.
Мертвый код может занимать до 30% программы, особенно при разработке приложений, поскольку к ним добавляются все новые и новые кусочки.
Проблема с мертвым кодом алгоритмически неразрешимый .
Это означает, что я не могу создать инструмент, который находил бы мертвый код для любой программы.
Заинтересовались этой проблемой в начале 50-х годов.
Соответствующие теорема Райса и теорема Успенского были доказаны одновременно и независимо, только Владимир Андреевич сформулировал ее более широко.
По сути, теоремы утверждают, что распознавание любого нетривиального свойства алгоритма является неразрешимой проблемой».
Хочу добавить, что в веб-программировании количество мёртвого кода обычно на порядок больше.
При своп-подключении его доля легко превышает порог в 80-90%.
То есть фактически будет выполнена только каждая 20-я строка кода.
Особенно хорошо это видно при использовании «тяжелых» фреймворков.
Сразу введем пару определений, которыми мы будем пользоваться ниже: монолит — код, не использующий внешние файловые соединения (включает) чистый монолит — монолит, в котором нет «мертвого» кода.
Справедливо возникли вопросы: насколько «мертвый» код и включения тормозят приложения? А в качестве решения проблем с производительностью и чистотой кода упомянули кэшеры опкодов , «волшебные» функции автоподключения классов и методов (далее для простоты будем называть это просто автозагрузка ), и быстрыйCGI .
Что ж, попробуем глубже разобраться в поставленном вопросе в поисках истины.
Итак, начнем.
Есть проблема?
Для начала попробуем выяснить, насколько вообще мертвый код и включения влияют на производительность.Начнем с мертвого кода.
Создаем страницы с 2000, 5000, 10000 строк кода и ставим на них apacheBenchmark. Мы получаем следующие результаты:
количество строк | запросов/сек | среднее время на запрос | мертвый код |
---|---|---|---|
2000 | 72.24 | 0.013 | 0 |
5000 | 32.20 | 0.031 | 0.6 |
10000 | 15.97 | 0.062 | 0.75 |
Здесь и ниже указано время, полученное на старом ноутбуке FS Amilo 1718. Результаты контрольных тестов, проведенных на разных системах с разными ОС и ФС, не отличались пропорциональноКак видите, время, затрачиваемое на обработку скрипта, на самом деле прямо пропорционально количеству строк в нем (что вполне логично, так как поскольку мы ничего не делаем в скрипте, то большая часть времени уходит только на его разбор .
Больше строк означает больше времени на анализ).
Сколько времени на этот раз? Это существенно .
Согласитесь, даже в идеале при отсутствии мёртвого кода 13 тысячных — это очень много (не говоря уже о 62, как в третьем тесте).
За это время можно отправить готовую страницу путем подключения к базе данных, запросов и т.д. Это всего лишь парсинг.
Теперь посмотрим на включения.
Мы смоделируем 4 ситуации: — «монолит» (без включений и мертвого кода) - «подкачка» (Имитирует безусловное подключение всех библиотек, которые обычно объединяются в большие файлы.
Предполагает мало включений больших файлов .
Много мертвого кода) — «автозагрузка» (Имитирует подключение классов/методов/функций при необходимости (обычно в момент вызова несуществующего класса/метода/функции).
Включает в себя множество включений мелких файлов .
Мертвого кода почти нет) — Пара промежуточных состояний между свопом и автозагрузкой.
Просто ради интереса.
Для полноты картины :) Результаты отображены в следующей таблице (в порядке производительности):
количество строк | включения | запросов/сек | среднее время на запрос | мертвый код | тип моделирования |
---|---|---|---|---|---|
2000 | 0 | 72.24 | 0.013 | 0 | чистый монолит |
2000 | 60 | 35.12 | 0.028 | 0 | автозагрузка |
5000 | 7 | 25.63 | 0.039 | 0.6 | — |
10500 | 14 | 13.2 | 0.076 | 0.81 | — |
15000 | 5 | 9.78 | 0.1 | 0.87 | менять |
Ну и своп нервно курит в сторонке :) (Правда, это только пока, потом автозагрузку задницу надерёт. Читайте статью дальше).
Но время обработки запроса все еще очень велико.
Кстати, эта таблица как раз подтверждает указанную мной цифру в результирующем выигрыше в 600% при переводе системы на чистый монолит.
Есть проблема – есть решение
Основным средством решения проблемы и повышения производительности приложений за счет снижения затрат на парсинг страниц являются кэши байт-кода.Наиболее известные системы кэширования (например, PHP) — это электронный акселератор , xCache И БТР .
Для тестирования был выбран eAccelerator, так как он является наиболее распространенным и быстрым в условиях нашей задачи.
Подробно о сравнении систем кэширования можно прочитать здесь.
Здесь .
Вот результаты использования кеша опкода (в порядке производительности):
количество строк | включения | запросов/сек (без кэша опкодов) | запросов/сек с кешем опкода | коэффициент ускорения | тип моделирования |
---|---|---|---|---|---|
2000 | 0 | 72.24 | 412.86 | 5.71 | чистый монолит |
15000 | 5 | 9.78 | 204.6 | 20.92 | менять |
10500 | 14 | 13.2 | 192.2 | 14.56 | — |
2000 | 60 | 35.12 | 112.11 | 3.19 | автозагрузка |
При использовании кеша опкода, несмотря на огромное количество мертвого кода соединение подкачки оказывается почти в 2 раза эффективнее автозагрузки ! И все благодаря безумному коэффициенту ускорения в 21x. Но коэффициент ускорения автозагрузки оказался самым низким — кэшер опкодов снизил затраты всего в 3 раза.
Отсюда делаем простой вывод: кеш опкода практически решает проблему «мертвого» кода, но не решает проблему включения .
Кэшеры также не любят большого количества мелких файлов, показывая на них наименьший прирост производительности.
А как насчет FastCGI?
По мнению многих, еще один способ ускорить работу скриптов и снизить стоимость загрузки скрипта — запустить PHP в режиме FastCGI. Это не верно! .Почему fastCGI не ускоряет PHP можно прочитать у Котерова Здесь .
Кстати, его тесты eAccelerator там проводились на примере Zend-фреймворк .
Результаты, полученные Дмитрием Котеровым, очень близки к приведенным в этой теме.
Заключение
Целью статьи было подробно рассмотреть влияние мертвого кода и включения внешних файлов в код на конечную производительность приложения.Как видите, влияние этих факторов весьма существенно.
Статья написана Напольский , по понятным причинам он не смог его опубликовать.
Всё + к его карме ;) Теги: #include #fastcgi #php #Разработка веб-сайтов
-
Обзор Сканера Документов Epson
19 Oct, 24 -
Знакомство С Qt Для Raspberry Pi 3
19 Oct, 24 -
Лучший Геймер — Ящерица
19 Oct, 24 -
Тонкости Scala: Изучаем Canbuildfrom
19 Oct, 24 -
Международная Зачистка От Google
19 Oct, 24