Подтвердить что ты не робот

Почему PHP использует кеши opcode, в то время как Java компилирует файлы байт-кода?

С моей точки зрения, как PHP, так и Java имеют аналогичную структуру. Сначала вы пишете код высокого уровня, который затем должен быть переведен в более простой формат кода, который должен быть выполнен виртуальной машиной. Одно отличие состоит в том, что PHP работает непосредственно из файлов исходного кода, в то время как Java хранит байт-код в .class файлах, откуда VM может их загрузить.

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

Решение похоже на загрузку так называемых Accelerators, которые в основном хранят скомпилированные результаты в кеше, а затем используют кэшированные коды операций вместо компиляция снова.

Другой подход, сделанный Facebook, заключается в полностью компилировать код PHP на другой язык.

Итак, мой вопрос: почему никто в мире PHP не делает то, что делает Java? Есть ли какие-то динамические элементы, которые действительно нужно перекомпилировать каждый раз или что-то в этом роде? В противном случае было бы разумнее скомпилировать все, когда код перейдет в производство, а затем просто сработает с этим.

4b9b3361

Ответ 1

Самое важное отличие состоит в том, что JVM имеет явную спецификацию, которая полностью охватывает байт-код. Это делает файлы байт-кода переносимыми и полезными не только для выполнения конкретной реализации JVM.

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

Ответ 2

Коды операций PHP не совпадают с файлами классов Java. Java файлы классов хорошо указаны и переносимы между машинами. PHP-коды не переносятся никоим образом. Например, у них есть адреса памяти, запеченные в них. Они являются строго деталями реализации интерпретатора PHP и не должны рассматриваться как байт-код Java.

Должен ли он быть таким? Нет, наверное, нет. Но исходный код PHP - это беспорядок, и в сообществе разработчиков PHP нет ни желания, ни политической воли, чтобы это произошло. Я думаю, что речь шла о том, как выпекать кеш-код операции в PHP 6, но PHP 6 умер, и я не знаю статуса этой идеи.

Ссылка: я написал phc, поэтому в течение нескольких лет я был довольно колен в реализации/компиляции PHP.

Ответ 3

Не совсем верно, что никто в мире PHP делает то, что делает Java. Проекты, такие как приложение приложений Alexey Zakhlestin, обеспечивают степень настойчивости, более похожую на контейнер Java-сервлетов (хотя его вдохновение - больше Rubys Rack и Pythons WSGI, чем Java )

Ответ 4

PHP не использует стандартный механизм для кодов операций. Я желаю, чтобы он либо застрял в стеке VM (python, java), либо в реестре VM (x86, perl6 и т.д.). Но он использует что-то совершенно доморощенное и там лежит ложь.

Он использует связанный список в памяти, в результате чего каждый код операции имеет результат → op1 → op2 и → . Теперь каждый из них представляет собой либо константы, либо записи в таблице temp и т.д. Эти указатели не могут быть сериализованы любым разумным способом.

Теперь люди достигли этого, используя элементы, такие как pecl/bcompiler, который выгружает поток на диск.

Но классы делают это еще более сложным, а это значит, что существуют потенциальные фрагменты кода, такие как

if(<conditon>)
{
   class XYZ() { }
}
else 
{
   class XYZ() { }
}

class ABC extends XYZ {}

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

Проблема указателя не является непреодолимой. Существует apc_bindump, который я никогда не беспокоился о том, чтобы зафиксировать загрузку целых записей кэша с диска непосредственно при каждом перезапуске. Но больно отлаживать все это, чтобы получить что-то, что еще нужно найти для всех указателей системы - дело apache слишком просто, потому что все php-процессы имеют одинаковые системные указатели из-за поведения fork. Старые версии fastcgi были медленнее, потому что раньше они использовали fork и init php, а php-fpm исправили это, делая это наоборот.

Но в конечном итоге то, что на самом деле отсутствует в PHP, - это желание изобретать формат байт-кода, выбросить текущий движок и все модули - переписать его с помощью виртуальной машины стека и построить JIT. Мне жаль, что у меня не было времени - парни fb почти там с их hiphop HHVM. Который приносит жертву eval() за более высокую производительность - это справедливая жертва:)

PS: Я парень, который не может найти время для обновления APC для 5.4 правильно

Ответ 5

Я думаю, что вы все дезинформированы. HHVM не является компилятором для другого языка - это виртуальная машина. Путаница заключается в том, что использование facebook для компиляции на С++, но этот подход был медленным для требований разработчиков (десять минут для компиляции только для проверки некоторых крошечных вещей).