Смотрите, есть массив типа: PHP: $base = [ '122', 'a111', '234233' ]; значения в нем являются уникальными, цифры и символы, от 1 до 20 символов длина, естественно их на много больше, десятки тыщ, по этому массиву будет очень часто осуществляться поиск, найти схождение, найти расхождение, ну типа есть какие то массивы и нужно выявить какие значения из этих массивов есть в $base или каких нет в $base. вопрос как хранить что бы был быстрый поиск, первый вариант это хранить так, как есть сейчас и выбирать при помощи array_intersect и array_diff, но это занимает какое то время. второй вариант, перевести значения в ключи, что бы было что то типа: PHP: $base = [ '122' => NULL, 'a111' => NULL, '234233' => NULL ]; и осуществлять поиск через цикл используя array_key_exists: PHP: $base = []; $arr = []; // тут значения не в виде ключей for($i = 0; $i < count($arr); $i++) { if (array_key_exists($arr[$i], $base)) { // какое то действие } // кстати isset($base[ $arr[$i] ]) почему то уже не срабатывает } как то так, такой вариант работает мгновенно, за 0 сек выполняется в отличии от первого (где то 10 сек при тестировании), но меня как то смущает что хранится в виде ключей.. массив будет записываться в файл. кто что скажет из профессионалов.
ну у меня как минимум 2 массива, первый основной $base а второй какой то и я искал только при помощи array_intersect и array_diff, по этому in_array не измерял, сейчас измерил, где то раз в 100 медленнее. --- Добавлено --- сейчас присмотрелся, что то когда в виде ключей я храню и проверяю через array_key_exists, работает не корректно, до этого показывало сколько должно было, сейчас почему то меньше..
@VLK, я попробовал так: PHP: $count = 100000; for ($i = 0; $i < 100000; $i++) { $base[] = $count--; } var_dump(array_flip($base)); $search = ['122', 444, 9999]; $search = array_flip($search); var_dump(array_intersect_key($base, $search)); /*вывод: array (size=3) 122 => int 99878 444 => int 99556 9999 => int 90001 */
Странно если тип ключа будет string то не находится. В документации вроде показывают что работает. --- Добавлено --- Все работает как надо, я забыл сохранить новое состояние $base; т.е. не хватает строчки : PHP: $base = array_flip($base)
Зачем такую глупость делать? http://secure.php.net/manual/ru/function.array-search.php не ? --- Добавлено --- PHP: $start = microtime(true); // тело скрипта $newarr = [ '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', '12qrwrq','12qrwrq','12qrwrq','12qrwrq','12qrwrq', 'search', '12wegwegwegqrwrq', '12qrwwegwegrq', '12qrwregwegq', '12qweerwrq', '12qrwrwegwegwegq', '12qrwrqewgweg', '12qrwrqwegweg', '12qrwrewgwegq', '12qrwrefeg', '12qrwrq', '12qrwrq', '12qrwrq' ]; $key = array_search('search', $newarr); echo $newarr[$key].'<br>'; $t = (microtime(true) - $start); print 'Время выполнения скрипта: '.number_format($t).' сек.'; Время выполнения! 0 сек. Результат на экране: search Время выполнения скрипта: 0 сек. Можно в другом формате. search Время выполнения скрипта: 3.0994415283203E-6 сек. И даже с массивом раз в 30 больше попробовал тоже 0 сек. В чём проблема. Два массива ? Слей в один. Смотри всё просто: http://secure.php.net/manual/ru/function.array-merge.php
@askanim, не глупость это. Особенность массивов пыха такая. Где-то в соседней теме @rodent90 приводил пример того, как хранятся значения. По ключам же поиск фактически нативный, от того и скорость выше. Потому при прочих равных лучше искать по ним.
@askanim у меня 2 массива, мне надо выбрать все значения из одного, которых нет в другом: PHP: $base = []; // около 30 000 записей $input = []; // около 20 000 записей // оба массива формата: [ 0 => 'key1', 1 => 'key2' ] и in_array тут не канает, короче так: PHP: $count = 0; for($i = 0; $i < count($input); $i++) { $key = $input[$i]; if ( !in_array($key, $base) ) { $count++; } } 1 проход выполняется за 165 сек. PHP: $base = array_flip($base); $count = 0; for($i = 0; $i < count($input); $i++) { $key = $input[$i]; if ( !array_key_exists($key, $base) ) { $count++; } } 50 проходов за 0 сек. PHP: $count = count( array_diff($input, $base) ); 50 проходов за 4 сек. PHP: $base = array_flip($base); $input = array_flip($input); $count = count( array_diff_key($input, $base) ); 50 проходов за 0 сек.
@mahmuzar спасибо за array_flip, как то я его упустил. --- Добавлено --- @askanim ты выше показал поиск одного значения, у меня их массив с 20 000 записей.
Когда записей становится дохрена, пых начинает вести себя чуть иначе и небольшая разница становится таки значительной. Тестировать нужно именно на десятках тысячах записей, желательно с примерно таким же содержимым.
@romach я же сказал, я сунул туда порядка 5 или 6 тысяч. --- Добавлено --- @romach и 0 сек показало --- Добавлено --- @romach вот попробовали бы то что я написал и посмотрели бы все вместе на результат, ноги не кому за то что попробовать можно, никто и кому рубит ьне собирается вроде.
Пиши бенчмарк, 20-30к. записей, что бы и просто массивы и SPL и разные варианты поиска. Пусть @Ganzal позапускает у себя на разных версиях пыха )
@romach я на 7-ке сделал. --- Добавлено --- @romach да я просто написал вариант я не говорю делать именно так. --- Добавлено --- @Ganzal Завтра утром по своему времени в эту тему закину. Потому что я уже ухожу, офис закрывается, а я еду не домой, так как сегодня пятница и пора бы отдохнуть за недельку. Поправка по твоему времени*.
Вот файл возвращающий гигантский массив... Но мне кажется там просто много у меня там гигантский.... там более 50к наверно даже. Короче вот код. PHP: $arr = require_once ROOT.'/rArr.php'; $t = (microtime(true) - $start); $key = array_search('search', $arr); echo $arr[$key].'<br>'; print 'Время выполнения скрипта: '.number_format($t).' сек.'; А вот сам файл который массив возвращает. https://yadi.sk/i/-IVy4NJVuAHrp Ссылка на скачивание файла. Сюда не влез слишком большой. 1 с фигом метра массив весит. --- Добавлено --- там за 100к значений в массиве, и обработка составила 1,4 секунды. По мне так это быстро для обработки массива то. А вообще мне кажется для такого изощрения нужны базы данных.
@VLK, ты можешь отказаться от цикла, используй https://secure.php.net/manual/ru/function.array-intersect-key.php/ т.е. этот код: PHP: $base = array_flip($base); $count = 0; for($i = 0; $i < count($input); $i++) { $key = $input[$i]; if ( !array_key_exists($key, $base) ) { $count++; } } можно написать так: PHP: $base = array_flip($base); $input = array_flip($input); var_dump(array_intersect_key($base, $search)); мне показалось он возвращает именно тот результат который тебе нужен.
@mahmuzar попробуй протестить у себя мой метод скажи какой результ даст --- Добавлено --- @romach могу завтра полностью задачу раскидать, написать несколько вариантов решения на мой взгляд. Но махмузар тоже дело предложил.
@askanim у тебя в файле данные повторяются. Для честности тестирования с другими методами - данные должны быть уникальны, наверное. Выкладывай завтра полные бенчсьюит, чтоб распаковал, запустил, получил результаты. Будет дополнительным плюсом, если результаты будут в человекодружелюбном виде выходить. Вроде такого:
Ну и до кучи: http://symfony.com/doc/current/components/console.html - что бы была красивая консолька http://symfony.com/doc/current/components/console/helpers/table.html - что бы рисовать там таблички https://github.com/fzaninotto/Faker - что бы нахерачить кучу случайных данных Проект на гитхаб, с небольшим ридми, что бы запустить мог не только @Ganzal )