Постоянно встречается задача проверки наличия значения в массиве. В PHP для этих целей часто используют функцию in_array которая принимает два аргумента: искомое значение (или массив значений) и массив, в котором будет произведён поиск. Если значение найдено, функция возвращает true, в противном случае false.
Описание проблемы
Пока значений в массиве немного, то всё работает быстро. Но как только массив разрастается до 10 000 – 20 000 элементов, начинаются проблемы.
Один мой скрипт должен был проверять элементы на уникальность, сделать это средствами БД не получалось, т.к. массив после запроса к базе модифицировался пару раз. В массиве хранились только числовые id элементов (это пригодится для решения). В какой-то момент элементов стало больше 60 000 и скрипт стал работать по 20-30 с. на локальном хосте, что крайне медленно.
Простым замером времени исполнения участков кода (с помощью функции microtime()) что проблема именно в in_array.
Решение проблемы
Если подумать, то перебирать весь массив каждый раз чтобы проверить существование в нём элемента глупо. Гораздо проще проверить существование конкретного элемента массива, без перебора остальных значений. Для этого вместо массива вида ключ => значение(ID элемента) нужно использовать массив вида ключ(ID элемента) => какое-то значение (например true).
В таком случае для проверки существования элемента в массиве достаточно использовать функцию isset(), в которую следует передавать переменную вида $имя_массива[искомый ID элемента].
После перехода на такой способ проверки скрипт стал отрабатывать за 1.2 с, что вполне нормально.
Искренне Ваш К.О. =)
Основная идея проста: поменять местами ключ и значение в ассоциативном массиве. Т.е. в коде вместо:
будет
Где вместо true может быть что угодно. В итоге чтобы проверить есть ли этот элемент в массиве, достаточно проверить определён ли искомый ключ:
Ответить