Оптимизация PHP require_once для низкого дискового ввода-вывода?

Q1) Я разрабатываю CMS (а чего нет!), но приоритет отдается кешированию. Кешируется буквально все. Строки БД, запросы идентификаторов БД, данные конфигурации, обработанные данные, скомпилированные шаблоны. В настоящее время он имеет два уровня кеширования.

Первый - это кеш кода операции или кеш памяти, такой как apc, eaccelerator, xcache или memcached. Если запись там не найдена, она ищется во вторичном медленном кэше, т.е. php включает.

Действительно ли кеширование кода операции быстрее, чем выполнение require_once для файла php с массивом данных var_export в нем? Мои тесты неубедительны, поскольку мой блок разработки (5.3 из XAMPP) продолжает выдавать ошибки при установке любой из вышеупомянутых программ.

Q2) В CMS есть множество вспомогательных классов, которые загружаются автоматически по запросу вместо загрузки всех файлов. В большинстве случаев перед каждым из них есть требование, поэтому автозагрузка не требуется, но вопрос не в этом. Поскольку в скрипт страницы может быть включено до 50/60 вспомогательных файлов, у меня есть ощущение, что, если бы сайт находился под давлением, он бы прогнулся из-за всех операций ввода-вывода, которые при этом возникают. На данный момент не обращайте внимания на наличие кэша вывода, который устранит необходимость в том, что я собираюсь предложить, а также на то, что кеши кодов операций сделают это спорным. Я попытался объединить все вспомогательные файлы, необходимые для выполнения скриптов, в один файл. Это достижимо и работает хорошо, однако имеет побочный эффект, заключающийся в значительном увеличении использования памяти, хотя технически используется один и тот же код.

Что вы думаете и думаете по этому поводу?


person buggedcom    schedule 31.03.2010    source источник
comment
Просто прочтите это. у него есть некоторые ответы, которые я искал stackoverflow.com/questions/209728/   -  person buggedcom    schedule 31.03.2010


Ответы (4)


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

person John Conde    schedule 31.03.2010
comment
Спасибо, но я понимаю, что это как бы указано в вопросе. Я просто спросил из-за того, что, если у кого-то, кто использовал cms, не было кеша опкодов. Многие хосты моих клиентов не разрешают их, потому что они официально не поддерживают их (+ они также вызывают ошибки сегментации, за которыми вы должны следить) - person buggedcom; 31.03.2010

Похоже, вы просто не представляете, что хотите кешировать (и почему).

Вы просто не можете сравнивать "кеш кода операции" и "require_once". Кэш кода операции будет кэшировать требуемый код, а также другой код.

person Your Common Sense    schedule 18.02.2012

Во-первых, имейте в виду, что ваша операционная система будет кэшировать файлы в памяти, если к ним обращаются достаточно часто.

Также не используйте require_once. Это значительно медленнее, чем require. Если вы не используете автозагрузчик, вам следует его использовать. Нет причин вручную включать файлы в современное приложение php (очень мало исключений).

50-60 вспомогательных файлов - это безумие. Разве нельзя их объединить? Разве вы не можете поместить их все в связанный вспомогательный класс, например OutputHelper или CacheHelper? Таким образом, вам нужно только включить класс, который, опять же, должен позаботиться о вашем автозагрузчике. Мне кажется, вы делаете что-то вроде добавления одной функции для каждого файла.

Кэширование кода операции значительно снижает использование памяти и скорость выполнения, но я не уверен, какое влияние это оказывает на операторы require.

person ryeguy    schedule 31.03.2010
comment
Нет, все эти файлы являются вспомогательными классами, а не функциями. Проблема в том, что если я использую require, вы получите ошибки повторного объявления класса, если один и тот же файл будет включен более одного раза. Я переключил все требования на include_once, как было предложено в другом потоке, и это кажется немного лучше. Что касается их включения вручную, они обычно не включаются вручную, многие из них загружаются автоматически, однако, если автоматически загружаемый класс расширяется или реализуется, то там есть требуемые положения, чтобы сэкономить на автозагрузке. - person buggedcom; 31.03.2010
comment
@buggedcom: Готов поспорить, что использовать include_once дороже, чем заставлять автозагрузчик работать немного сложнее, когда вы расширяете класс, и он должен загружать своего родителя. Фреймворки очень сложные и большие, но ни один из них не включает в себя руководство. - person ryeguy; 31.03.2010
comment
@ryeguy: По способу настройки автозагрузчика это возможно. Я думал, что это действительно лучше для производительности? - person buggedcom; 01.04.2010
comment
@buggedcom: Не уверен, что понимаю, о чем вы говорите. Если я вас правильно понял, вы вручную включаете родительский класс ребенка? Например, у вас есть class Widget extends AbstractWidget, и вы бы сделали include_once 'AbstractWidget.php' в своем Widget.php файле, верно? Я имел в виду, что да, вы избавляете автозагрузчик от необходимости находить здесь Widget.php, но использование (require|include)_once происходит медленно, потому что PHP должен выполнять внутренние проверки, чтобы увидеть, был ли файл включен ранее. - person ryeguy; 01.04.2010
comment
Да, вы, по сути, поняли, что я делаю. Я понял, что использование функции автозагрузчика само по себе было медленным, поэтому требовалось выполнить требование один раз. Так что, возможно, лучшим решением было бы использовать мою собственную функцию загрузки, которая в сочетании с автозагрузкой может видеть, загружен ли уже запрошенный файл? Я думаю, что требуется некоторый бенчмаркинг. - person buggedcom; 01.04.2010
comment
Только что провел очень-очень быстрый тест, основанный на выполнении 10 страниц, загружающих 40 нечетных включений, 10 при использовании include_once и 10 при использовании автозагрузки. Хотя это довольно неубедительно, автозагрузка была быстрее, в среднем на 0,00744407176969 секунд. Теперь это может показаться не таким уж большим, но на самом деле это так. Я протестирую функцию загрузки самостоятельно и также отправлю ее обратно. - person buggedcom; 01.04.2010
comment
не используйте require_once. Это значительно медленнее, чем требуется. Есть ли какие-либо ссылки или тесты? - person Yousha Aleayoub; 10.09.2020

Я согласен с Райгуем. require_once работает медленнее, чем require или include, потому что он должен регистрировать каждое включение и проверять его. Если вы делаете только один require / include (который должен быть для классов), вам не нужны require_once или include_once.

Автозагрузка отлично подходит для оптимизации. Поскольку вы будете загружать классы только при необходимости. Итак, если ваше приложение имеет 500 классов, но для запуска определенной страницы / скрипта требуется только 15. Тогда загружаются только те 15. Что приятно.

Если вы взглянете на какой-нибудь большой фреймворк. Вы заметите, что они перешли на использование автозагрузчиков. Они используют require_once в последний момент, как в этом примере из Zend Framework версии 1.

require_once 'Zend/Db/Exception.php';
throw new Zend_Db_Exception('Adapter name must be specified in a string');

Zend Framework Version 2 вместо этого будет использовать автозагрузчики. Я считаю, что это самый быстрый вариант, и его проще всего кодировать.

person Sean Thayne    schedule 18.02.2012
comment
OMG, какую ссылку вы разместили. Кажется, этот парень совершенно не понимает, что делает. Запускать * _once тысячу раз для каждого экземпляра абсолютно бессмысленно. - person Your Common Sense; 18.02.2012
comment
Вот в чем суть. Вы не можете сравнить require_once, запустив его 1000 раз в цикле. Потому что в реальной жизни все вызывается только ОДИН РАЗ. Однажды, разве вы этого не понимаете? В реальной жизни разницы в скорости нет. - person Your Common Sense; 02.04.2012
comment
Ах, теперь я понимаю, о чем вы говорите. Спасибо за объяснение. - person Sean Thayne; 03.04.2012