Я пытаюсь понять как array_merge
а также union
работать за кулисами в PHP из любопытства.
Может ли кто-нибудь помочь мне понять внутренности ZEND за кулисами:
array_merge
(медленнее на процессоре и оперативной памяти)UNION
(быстрее во всех аспектах)Вот код теста, который я использую: https://gist.github.com/EnchanterIO/6e90f828c1b32c894d35267c353e83d2
Вывод с использованием PHP 7:
Ray ArrayMerge git: (master) ✗ php src / benchmark.php array_merge 20000
Построение массива из 20000 элементов с использованием array_merge заняло 7 секунд.
Использование памяти составляет: 8 МБ. Пик памяти составил: 12288 МБ.
Ray ArrayMerge git: (master) ✗ php src / benchmark.php union 20000
Создание массива из 20000 элементов с использованием объединения заняло 0 секунд.
Использование памяти составляет: 8 МБ. Пик памяти составил: 10240 МБ.
Моя теория для array_merge:
Я смотрю на PHP исходный код написан на C для объединения массивов (если это даже правильное место) и хотя это немного нечитаемо для меня, так как я не знаком с жаргоном, кажется, что причина, почему array_merge
медленнее из-за необходимости дополнительного foreach, а также из-за того, что array_merge
перенумеровывает цифровые ключи в результирующем массиве.
Моя теория для UNION:
Не нашел исходного кода для него, но, насколько я знаю, добавление элементов в массив работает так:
Может кто-нибудь пролить больше света на процесс и подробно объяснить скрытую магию ZEND?
Обновить:
Меня сослали на следующие ссылки, но я все еще не могу понять, как это сделать:
https://lxr.room11.org/xref/php-src%40master/Zend/zend_opcode.c#740
https://lxr.room11.org/xref/php-src%40master/Zend/zend_operators.c#897
https://lxr.room11.org/xref/php-src%40master/Zend/zend_hash.c#1915
Я полагаю, что мой тест был несправедливым, потому что (надеюсь, никто не имеет здравого смысла) перебирает массив и затем использует array_merge объединить один элемент.
Я создал новый эталонный тест показывая разницу между объединением двух больших массивов в один foreach и ручное добавление и используя array_merge.
Результат
Нет преимущества в производительности при объединении двух массивов вручную по сравнению с объединением их с array_merge.
Других решений пока нет …