Рубрика: Оптимизация

  • Анатомия zval: Основные компоненты (PHP 7+)

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

    2.1. Основные компоненты zval

    Структура _zval_struct

    struct _zval_struct {
        zend_value value;    // Основное значение (64 бита)
        union {
            struct {
                zend_uchar type;         // Тип данных (IS_LONG, IS_STRING и др.)
                zend_uchar type_flags;    // Флаги поведения типа
                zend_uchar const_flags;   // Флаги константности
                zend_uchar reserved;      // Зарезервировано
            } v;
            uint32_t type_info;           // Альтернативное представление
        } u1;                            // 32 бита
        union u2 {                       // 32 бита (служебные данные)
            uint32_t next;               // Для управления хеш-таблицами
            uint32_t cache_slot;         // Кеширование
            uint32_t lineno;             // Номер строки (для ошибок)
            uint32_t num_args;           // Количество аргументов
            uint32_t fe_pos;             // Позиция в foreach
            // ... другие служебные поля
        };
    }; // Всего 16 байт

    1. Компонент value (zend_value)

    ТипПолеРазмерОписание
    Целоеlval64 битаДля типов IS_LONG, IS_BOOL
    Дробноеdval64 битаДля IS_DOUBLE
    Указательstr64 битаДля строк (IS_STRING)
    Указательarr64 битаДля массивов (IS_ARRAY)

    2. Компонент u1 (метаданные типа)

    • type — определяет базовый тип данных (IS_LONG, IS_STRING и др.)
    • type_flags — дополнительные флаги поведения:
      • IS_TYPE_REFCOUNTED (требует подсчета ссылок)
      • IS_TYPE_COPYABLE (поддерживает Copy-On-Write)
      • IS_TYPE_IMMUTABLE (неизменяемый тип)
    • const_flags — флаги константности

    3. Компонент u2 (служебные данные)

    Этот компонент используется для различных оптимизаций:

    • next — связь элементов в хеш-таблицах
    • cache_slot — кеширование для быстрого доступа
    • lineno — отладка (номер строки в исходном коде)
    • num_args — информация о вызовах функций

    Практический пример

    // Создание zval с целым числом
    zval my_zval;
    ZVAL_LONG(&my_zval, 42);
    
    // Доступ к данным
    if (Z_TYPE(my_zval) == IS_LONG) {
        zend_long value = Z_LVAL(my_zval); // 42
        php_printf("Значение: %ld\n", value);
    }

    Продолжение следует в следующей статье цикла…

  • Введение в устройство zval: фундамент обработки данных в PHP

    Zval (Zend value) — фундаментальная структура данных в ядре PHP, ответственная за хранение и обработку всех переменных. В этой статье мы исследуем её эволюцию, современную реализацию и практическое значение для разработчиков.

    Историческая эволюция zval

    PHP 5: Первое поколение

    • 24-байтовая структура
    • Универсальный подсчет ссылок
    • Высокие накладные расходы

    PHP 7: Революция

    • 16 байт (экономия 33%)
    • Разделение value/type
    • Оптимизация скаляров

    PHP 8: Совершенство

    • Дополнительные оптимизации
    • Интеграция с JIT
    • Улучшенные хеш-таблицы

    Структура zval в PHP 8

    struct _zval_struct {
        zend_value value;    // 64-битное значение
        union {
            struct {
                zend_uchar type;        // Тип данных
                zend_uchar type_flags;  // Флаги поведения
                zend_uchar const_flags; // Константность
                zend_uchar reserved;    // Выравнивание
            } v;
            uint32_t type_info;
        } u1;
        union u2 {
            uint32_t next;
            // ... служебные поля
        };
    }; // Всего 16 байт

    Ключевые оптимизации

    • Отказ от refcount для скаляров — целые числа и булевы значения больше не используют подсчет ссылок
    • Copy-On-Write — сложные структуры копируются только при модификации
    • Встроенное кеширование хешей — ускорение операций сравнения строк
    • Оптимизированные хеш-таблицы — быстрый доступ к элементам массивов

    Практическое применение для разработчиков и авторов расширений

    • Оптимизация потребления памяти
    • Эффективная работа с переменными
    • Понимание поведения типов

    Пример:

    // Создание строки в расширении
    zend_string *str = zend_string_init("test", 4, 0);
    zval zv;
    ZVAL_STR(&zv, str);

  • Внутреннее устройство PHP: глубокий разбор структуры zval

    Zval (Zend value) — фундаментальная структура данных в ядре PHP, ответственная за хранение и обработку всех переменных. В этой статье мы детально разберем её эволюцию и современную реализацию.

    Историческая эволюция

    Версия PHPРазмер zvalКлючевые изменения
    PHP 5.624 байтаУниверсальный подсчет ссылок, избыточность
    PHP 7.016 байтОптимизация хранения скаляров, новые флаги
    PHP 8.216 байтДополнительные оптимизации JIT

    Сравнение производительности

    // Тест создания 1 млн zval-ов (в нс)
    PHP 5.6: 2400 ns
    PHP 8.2: 800 ns (ускорение 3x)

    Структура zval в PHP 8

    struct _zval_struct {
        zend_value value;    // 8 байт (union)
        union {
            struct {
                zend_uchar type;        // Тип данных
                zend_uchar type_flags;  // Поведенческие флаги
                zend_uchar const_flags; // Константность
                zend_uchar reserved;    // Выравнивание
            } v;
            uint32_t type_info;         // Альтернативное представление
        } u1;                          // 4 байта
        union u2 {                     // 4 байта (служебные данные)
            uint32_t next;
            // ... другие поля
        };
    }; // Всего 16 байт

    Типы данных и их хранение

    • Скаляры (int, float, bool) — хранятся напрямую в zend_value
    • Строки — указатель на zend_string (отдельная структура в heap)
    • Массивы — указатель на HashTable
    • Объекты — указатель на zend_object

    Ключевые оптимизации

    1. Отказ от refcount для скаляров

    В PHP 7+ целые числа и булевы значения больше не используют подсчет ссылок, что устраняет накладные расходы на их копирование.

    2. Copy-On-Write для сложных структур

    $a = [1,2,3]; // Создается HashTable (refcount=1)
    $b = $a;      // Только увеличивается refcount
    $b[] = 4;     // Реальное копирование при изменении

    3. Встроенное кеширование хешей

    Строки хранят предвычисленные хеши, что ускоряет операции сравнения и поиска в хеш-таблицах.

    Практическое применение

    Для разработчиков расширений

    // Создание zval в расширении
    zval my_zval;
    ZVAL_LONG(&my_zval, 42);
    
    // Доступ к значению
    if (Z_TYPE(my_zval) == IS_LONG) {
        zend_long value = Z_LVAL(my_zval);
    }

    Оптимизации для веб-приложений

    • Используйте строгие типы (strict_types=1)
    • Избегайте избыточного копирования массивов
    • Освобождайте память unset() для больших структур

    Заключение

    • Zval в PHP 8 — высокооптимизированная структура
    • Понимание её устройства помогает писать эффективный код
    • Оптимизации PHP 7+ дают до 3x прирост производительности