Особенности PHP 7+: строки, массивы и Copy on write
Рассказываем об особенностях языка программирования PHP от 7 версии. Рассматриваем строки, массивы, Interned variables и Copy on write.
2К открытий4К показов
Все популярные языки программирования похожи, они основываются на общих фундаментальных концепциях. Были разработаны и развиваются с учетом лучших практик. Несмотря на сходства, каждый язык программирования также имеет свои уникальные особенности, в этой статье поговорим о некоторых особенностях языка PHP (7+).
Принцип работы PHP
Стандартный путь выполнения PHP скрипта следующий: поступает запрос на выполнение PHP скрипта, создается процесс выполнения, где PHP код компилируется в байт-код. Далее байт-код оптимизируется и исполняется виртуальной машиной (ZEND). После выполнения, процесс уничтожается со всей сопутствующей информацией, и при повторном вызове процесс полностью создается заново. Поэтому существует такое выражение: “PHP рождён, чтобы умирать”.
Ситуацию меняют OPcache и JIT. OPcache (Opcode Cache) – это расширение для PHP, которое выполняет кэширование скомпилированного байт-кода PHP. OPcache сохраняет этот скомпилированный байт-код в памяти, чтобы избежать повторной компиляции при каждом запросе. JIT (Just-In-Time) генерирует и кэширует машинный код из оптимизированного байт-кода, который без изменений может вызывать интерпретатор. JIT работает только с теми частями кода, которые активно используются во время выполнения.
Copy on write
Механизм Copy on write используется для оптимизации использования памяти. В PHP, когда передается значение в функцию или одна переменная присваивается другой (и во многих других случаях), то будет создана отдельная копия значения:
Очевидно, что если передать большой массив в функцию, то выделение ресурсов на его копирование не сулит ничем хорошим. Чтобы избежать лишнего копирования, PHP использует copy on write: копирование значения происходит только при его модификации:
Стоит заметить, что копирование это не совсем копирование в привычном понимании. Это означает, что если вы “копируете” значение, вы на самом деле повторно используете старое значение и увеличиваете его счетчик ссылок (refcount). Только после того, как вы выполните какую-либо модификацию, будет сделана реальная копия (дубликат).
Строки
Строка (тип string) – это набор символов, где символ – это то же самое, что и байт. Это значит, что PHP поддерживает ровно 256 различных символов, а также то, что в PHP нет встроенной поддержки многобайтовых кодировок. Для работы с ними есть расширение mbstring, которое предоставляет функции для работы с многобайтовыми строками:
Кавычки
Строки в разных кавычках обрабатываются по разному. В двойных кавычках PHP будет искать и обрабатывать переменные, следовательно, будет тратить больше ресурсов на обработку. Это также касается и функций вывода строк: echo и print будут оптимальнее чем printf.
Interned variables
В PHP хранение переменных осуществляется в variable containers, это значит, что можно повторно использовать переменные, память при это не выделяется.
На примере строк: Interned strings относится к процессу оптимизации памяти, при котором один экземпляр строки хранится в памяти и используется повторно, вместо создания дубликатов этой строки.
Когда вы объявляете строковую переменную в PHP, например:
Обычно каждая строка будет иметь свой собственный экземпляр в памяти. Однако, PHP оптимизирует использование памяти и делает так, чтобы обе переменные ссылались на один и тот же экземпляр строки “Hello”. Но, если строки создаются динамически или изменяются во время выполнения программы, они не будут интернированы.
Массивы
Массивы в PHP отличаются от классических массивов в других языках. В PHP массивы это упорядоченные словари, но в зависимости от ключей, интерпретатор выбирает наиболее оптимальное внутреннее представление массива. Выделить можно 3 типа массивов: неизменяемые, packed array и обычные массивы.
Неизменяемый массив заполнен неизменяемыми элементами, чьи значения не требуют вычислений и известны во время компиляции.
Packed array получается в случае, когда ключи массива это целые числа в порядке возрастания. Он занимает меньше памяти (чем обычный массив) и прост для итерации.
Packed array:
Обычный массив (добавим ключ с типом string):
Потребление памяти заметно стало больше.
Обход массивов
Обход также будет отличатся для packed и обычных массивов.
При обходе packed array, функции использующие callback (map, filter и другие) и foreach будут менее эффективны по памяти и производительности чем циклы for и while:
Через цикл for:
При обходе массивов со смешанными ключами, все циклы плюс минус одинаковы по производительности.
Заключение
Мы рассмотрели несколько особенностей PHP. Язык постоянно развивается, оптимизируется и становится лучше. Если было полезно, ставьте классы. Всем добра!
2К открытий4К показов