Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Быстрая проверка существования строки среди других

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
Edwvee
Отправлено: 24 Октября, 2013 - 15:10:37
Post Id


Частый гость


Покинул форум
Сообщений всего: 195
Дата рег-ции: Июнь 2013  


Помог: 1 раз(а)




Есть уникальные строки, есть потребность проверить существует ли среди них какая-либо строка. Интересно как в php добиться в этом максимальной скорости. Пока идея такая:
PHP:
скопировать код в буфер обмена
  1.  
  2. //тестовое представление структуры для поиска в ней
  3. $strings = array();
  4. for($i = 0; $i<1000000; ++$i)
  5. {
  6.     $strings[$i] = true; //значение не важно, надеюсь булевый тип меньше всего занимает память в php
  7. }
  8.  
  9. ...//тут другой код и инициализируется переменая $key
  10.  
  11. if (isset($strings[$key]))
  12. {
  13.    ...
  14. }
  15.  

(Отредактировано автором: 24 Октября, 2013 - 15:12:26)

 
 Top
IllusionMH
Отправлено: 24 Октября, 2013 - 15:16:58
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)




Edwvee, array_search?
 
 Top
Edwvee
Отправлено: 24 Октября, 2013 - 15:54:15
Post Id


Частый гость


Покинул форум
Сообщений всего: 195
Дата рег-ции: Июнь 2013  


Помог: 1 раз(а)




Неа, для этой цели фигня. Если ищется существующее значение, то одно и то же время тратится. Если же ищется значение которое не существует, то при выполнении скриптов ниже у меня с моим способом выполняется за то же самое время 0.15, c array_search за 9-14 секунд на протестированнных значениях.
Скрипт с моим способом:
PHP:
скопировать код в буфер обмена
  1.  
  2. $strings = array();
  3.  
  4. $startTime = microtime(true);
  5. for($i = 0; $i<100000; ++$i)
  6. {
  7.     $strings[md5($i)] = true;
  8. }
  9.  
  10. for ($j = 0; $j<1000; $j++)
  11. {
  12.         if (isset($strings[$key]))
  13.         {
  14.            echo 'found!';
  15.         }
  16. }
  17. $endTime = microtime(true);
  18. $time = $endTime - $startTime;
  19.  
  20. echo '<br>';
  21. echo $time;
  22.  


Скрипт с array_search:
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. $strings = array();
  4.  
  5. $startTime = microtime(true);
  6. for($i = 0; $i<100000; ++$i)
  7. {
  8.     $strings[] = md5($i);
  9. }
  10.  
  11. for ($j = 0; $j<1000; $j++)
  12. {
  13.         if (array_search($key, $strings))
  14.         {
  15.            echo 'found!';
  16.         }
  17. }
  18. $endTime = microtime(true);
  19. $time = $endTime - $startTime;
  20.  
  21. echo '<br>';
  22. echo $time;
  23.  


Попробуйте реализовать оба с
$key = md5(10000), например
и $key = md5(10000000000)

Я думаю код примерно одинаков по нагрузке для этих двух методов.

Может можно быстрее?

(Отредактировано автором: 24 Октября, 2013 - 15:56:48)

 
 Top
Ch_chov
Отправлено: 24 Октября, 2013 - 16:01:54
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




Нафига array_search внутри цикла?
 
 Top
Edwvee
Отправлено: 24 Октября, 2013 - 16:02:51
Post Id


Частый гость


Покинул форум
Сообщений всего: 195
Дата рег-ции: Июнь 2013  


Помог: 1 раз(а)




У меня если что apache на винде стоит, что есть не подходящая платформа для него и пхп.
На линуксовой машине оказалось ~0.5c мой способ и примерно ~4c cпособ с array_search
(Добавление)
Ch_chov пишет:
Нафига array_search внутри цикла?

Чтобы измеряемое время имело какое-то весомое и усредненное значение. Все-таки время выполнения одной инструкции это почти что на уровне погрешности, тем более может быть ощутимый разброс

(Отредактировано автором: 24 Октября, 2013 - 16:05:29)

 
 Top
Ch_chov
Отправлено: 24 Октября, 2013 - 16:11:38
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




Ясно. Ну если разделить полученное значение на 1000 то результат будет в микросекундах. Поэтому нет никакого смысла с этим заморачиваться. Для поиска ключей в массиве есть array_key_exist

http://ilia[dot]ws/archives/247-Performance-Analysis-of-isset-vs-array_key_exists.html
 
 Top
Edwvee
Отправлено: 24 Октября, 2013 - 16:24:48
Post Id


Частый гость


Покинул форум
Сообщений всего: 195
Дата рег-ции: Июнь 2013  


Помог: 1 раз(а)




Измеряется же не только время выполнения инструкций среднее, но и время для создания такого массива.
Насчет array_key_exists:
Время то же самое, выходит, но символов больше. А свойство ниже в данном случае не влияет на результат, так как нигде null не присваивается.
Цитата:
isset() does not return TRUE for array keys that correspond to a NULL value, while array_key_exists() does.
 
 Top
Мелкий Супермодератор
Отправлено: 24 Октября, 2013 - 16:26:52
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Edwvee, для чего вы включили во время теста время генерации тестовых данных? Для получения статистического времени поиска в массиве, а не времени генерации тестовых данных, надо считать только время поиска, а так же количество итераций увеличить ещё хотя бы на 3-4 порядка.

По ключу всегда искать быстрее, чем по значению.


-----
PostgreSQL DBA
 
 Top
Edwvee
Отправлено: 24 Октября, 2013 - 16:48:25
Post Id


Частый гость


Покинул форум
Сообщений всего: 195
Дата рег-ции: Июнь 2013  


Помог: 1 раз(а)




Реальная задача недавняя
Есть таблица в бд, есть потребность загрузить из csv файла в эту таблицу, только нужно было в таблице сохранить уникальность сочетания столбец1, столбец2, столбец3. Я грузил таблицу целиком(меньше 50000 записей), формировал из записей строки по этим трем столбцам, и по записям из цсв файла тоже, и искал наличие строки из цсв файла в строках из бд, чтобы знать отсылать ли ее на insert. Так что время формирования нужной формы данных тоже влияет(может оно и не отличается особо в этих двух способах). Да и думаю во многих задачах представление набора строк можно формировать и так, и так.
 
 Top
Мелкий Супермодератор
Отправлено: 24 Октября, 2013 - 17:00:51
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Edwvee пишет:
Так что время формирования нужной формы данных тоже влияет

Не влияет. Вы изобрели hash-индекс, его штатное свойство - врать о позитивных срабатываниях, но врать быстро.

Уникальный индекс и insert ignore или insert ... on duplicate key решает большинство поставленных вопросов.
create temporary table и последующим join'ом по having count(0)>1 и разруливанием из кода, какую из версию надо оставить, решает все остальные проблемы.
А ещё есть LOAD DATA.


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Хранение данных, их вывод и обработка »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB