Определенно, будет полезно на больших наборах данных или в циклах.
Повторю основной принцип:
// Создается новый ассоциативный массив,
// где в качестве ключей получается искомое значение
foreach(array_values($haystack) as $v)
$new_haystack[$v] = 1;
// Теперь можно определить вхождение по ключу
if(isset($haystack[$needle]))
reutrn true;
Как утверждает автор, такой подход ускоряет работу примерно в 280 раз.
Для малых массивов я бы использовать такой обработчик не стал, но вот в каких-либо импортах или обработках данных самое то.
Олег Постоев написал: Мне интересно. Можете привести пример из практики, когда вы отказались от реализации на PHP и использовали что-то другое, на что?
Вопрос был задан не мне, но приведу пару примеров из своего опыта:
1) Стояла задача экспорта в Excel большого объема данных.
Выгрузка 60000 строк с формулами, автофильтрами и форматированием, реализованная с помощью PHPExcel, занимала более 10 минут, причем процессу требовалось несколько ГБ оперативной памяти.
В итоге, вместо PHPExcel был использован Python (библиотека XlsxWriter): скрипт PHP генерировал данные в формате CSV и передавал их скрипту на Python с помощью exec. Время выгрузки сократилось до 15 секунд, память практически не использовалась.
Самое интересное, что реализация на Python заняла меньше времени, чем на PHP, из-за того что XlsxWriter оказался интуитивно понятным и гораздо более предсказуемым, чем PHPExcel.
2) Стояла задача импорта 8 000 000 значений остатков из внешний системы каждые полчаса.
Внешняя система не умела работать в инкрементальном режиме — каждый раз передавались все данные, даже если они не изменились с последнего импорта. Даже после суровой цирковой оптимизации, реализация импорта такого объема данных на PHP занимала больше получаса, то есть, не была рабочей. Кроме того, она сильно нагружала базу данных.
В итоге, было использовано альтернативное решение:
- исходный файл импорта преобразовывался с помощью bash + sed к удобному для MySql виду; - на slave сервере базы данных выполнялся SET SQL_LOG_BIN=0; - далее в рамках того же соединения создавалась таблица; - в таблицу с помощью LOAD DATA INFILE заливались подготовленные данные; - по окончании заливки строился индекс; - выполнялся запрос на сравнение данных между основной и новой таблицами; - на основании запроса генерировались bulk replace запросы к основной таблице, по 100 значений на запрос;
Результатом стало сокращение времени работы импорта до 2-х минут. Нагрузка на Slave базу данных получилась умеренной, на остальные — практически незаметной.
3) Стояла задача реализовать морфологический анализатор для русского языка (часть внутренней системы).
В качестве хранения данных была выбрана структура DAWG, как наиболее оптимальная для решения этой задачи по соотношению сложность/скорость работы. Реализация DAWG графа на чистом PHP с помощью объектов оказалась нерабочей: попытка загрузить словарь в структуру приводил к выпадению скрипта по памяти, не хватало и 10 ГБ.
В итоге, решением стало использование готовой библиотеки для работы с DAWG, написанной на Cи. Сам анализатор был также выполнен на Си в виде FastCGI приложения с предзагруженным словарем. В качестве менеджера процессов использовался spawn-fcgi. Расход памяти на процесс, в итоге, составил менее 4 Мб, а скорость работы просто потрясающей.
Можно вспомнить и другие примеры. PHP — отличный язык, но его область применения — это генерация web страниц. Пытаться решать с его помощью все что только можно — неправильно. Для каждой задачи должен быть свой инструмент. И если для решения проблемы требуется запихать в массив PHP тысячи элементов, то это верный признак того, что инструмент выбран неверно.
Еще пример, где PHP бессилен - боты на сервере. Замена - node.js. Не та замена, про которую кричат на Хабре "node.js это круто", а именно замена по месту - когда необходимо
(выкручиваться с ботами в рамках PHP можно, но до определенного момента, когда банально невыгодно становится)
c помощью проекта peachpie.io который компилит PHP в .NET байткод а как известно Microsoft релизнула .NET на линуксы. так что в скором времен на PHP можно будет писать все что угодно.
Иван написал: ) Стояла задача экспорта в Excel большого объема данных.
может стоило откзааться от этого идиотского формата и использовать экспорт в csv http://php.net/manual/ru/function.fputcsv.php которы можно поточно читать и писать не сжирая гигабайты памяти а парсер вовсе элементарен
скрипт PHP генерировал данные в формате CSV и передавал их скрипту на Python с помощью exec. Время выгрузки сократилось до 15 секунд, память практически не использовалась.
так и произошло) и в итоге питон победил))
PHPExcel - это капец, в нем можно только с xlsx работать, которые по сути xml, а файлы старого экселя махом всю память съедают
Алексей Минеев, просто непонятно зачм питон - если в php из коробки есть работа с csv
xls сам по себе формат не поточный и давно устарел. так что говорим клиенту - покупай памяти достаточно если так нужен формат xls. еще лучше windows и ms office если хотят чтобы файлы были 100% совместимы и без проблем открывалсь.
ну а для тех кто шарит в экономии денег - есть xlsx https://github.com/mk-j/PHP_XLSXWriter поддерживает поточную запись. и не имеет проблем с отжиранием памяти. к тому же не конфилктует с требованием bitrix mbstring.func_overload
к тому же если у вас питон - это яно не шаредхостинг - и по мне так дешевле памяти добавить чем вносить дополнительные затраты в виде разработки и поддержки на питоне.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».