Russian Qt Forum
Ноябрь 23, 2024, 00:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Быстрый поиск подходящего значения  (Прочитано 5902 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Январь 12, 2011, 17:21 »

Добрый день

Есть двухсвязный список каждый элемент которого имеет целое значение (ключ).  Задача: как можно быстрее найти любой элемент со значением меньше заданного порога N. Список может меняться от одного поиска ко другому, однако N (порог) может только увеличиваться при следующем поиске.  

Критично по скорости, так что "no containers/STL etc. please"

Спасибо
Записан
SimpleSunny
Гость
« Ответ #1 : Январь 12, 2011, 19:14 »

А список как заполняется?
Может стоит на этапе заполнения попутно искать такой элемент.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Январь 12, 2011, 19:53 »

А список как заполняется?
Может стоит на этапе заполнения попутно искать такой элемент.
Так и было  Улыбающийся (это подзадача для "потокобезопасного кэша"). На 1 нитке действительно все Ок. как только обращаемся к элементу кэша, пере-линкуем его в голову списка. Это стандартная реализация LRU кэша (и Qt тоже). Однако с 2 и более нитками такая перелинковка требует блокировки, и это обходится очень дорого при интенсивном использовании кэша. Прямой перебор значительно быстрее, вот как бы его маленько улучшить?
Записан
alexman
Гость
« Ответ #3 : Январь 12, 2011, 21:15 »

Не знаю правильно ли я понял, но можно попробовать хранить индекс, а при добавлении элемента перестраивать индекс. Ну а далее поиск займет O(log(длина списка)).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Январь 12, 2011, 21:24 »

Не знаю правильно ли я понял, но можно попробовать хранить индекс, а при добавлении элемента перестраивать индекс. Ну а далее поиск займет O(log(длина списка)).
Неправильно. В списке нет индекса, просто каждый элемент указывает на следующий (и предыдущий). "Перестраивать при добавлении" не катит по причинам изложенным в #2
Записан
alexman
Гость
« Ответ #5 : Январь 12, 2011, 21:33 »

Не знаю правильно ли я понял, но можно попробовать хранить индекс, а при добавлении элемента перестраивать индекс. Ну а далее поиск займет O(log(длина списка)).
Неправильно. В списке нет индекса, просто каждый элемент указывает на следующий (и предыдущий). "Перестраивать при добавлении" не катит по причинам изложенным в #2
Так что нельзя организовать индекс-сортировку в отдельном контейнере?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Январь 12, 2011, 21:56 »

Так что нельзя организовать индекс-сортировку в отдельном контейнере?
Цитировать
Муля, не нервируй меня
В теме ясно сказано "крытычно по скорости"
Записан
Waryable
Гость
« Ответ #7 : Январь 19, 2011, 05:29 »

Однако с 2 и более нитками такая перелинковка требует блокировки, и это обходится очень дорого при интенсивном использовании кэша. Прямой перебор значительно быстрее...
Здесь у меня взникает вопрос: получается, что во время перебора последовательности изменение самой последовательности не критично? Иначе перебор сам потребует блока.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Январь 19, 2011, 10:49 »

Здесь у меня взникает вопрос: получается, что во время перебора последовательности изменение самой последовательности не критично? Иначе перебор сам потребует блока.
Допускается любое изменение изменение порядка данных в списке (но не их удаление/добавление/изменение). Прелесть "списка" в том что он позволяет делать перестановки без всяких доп. блоков.

Первое что приходит в голову: "а давайте сначала пройдемся по всему списку и все подходящие элементы перенесем в начало - и тогда на следующих запросах уже будем просто подряд брать"

Но так не проходит  Улыбающийся Подходящих может быть очень мало, и молотьба по всему списку в минус. Да и ключи подходящих могут "подрасти" к следующему запросу - и они уже будут "неподходящими"
Записан
Waryable
Гость
« Ответ #9 : Январь 19, 2011, 14:09 »

Вот что я думаю. Если уж есть требование к высокоскорострельности алгоритма, то нужно знать чуть больше, чем просто список и порог для поиска. Как минимум хорошо было бы знать характер содержимого списка: частично сортирован(тенденция уменьшения/возрастания ключей слева-направо), максимальные значения ключей, размер списка... Возможно что-то еще понадобится.
Ну а на сколько я мог судить список частично сортирован. Поэтому искать надо с конца, где наименьшие значения. Но опять же, не зная принципа получения значения порога N во время текущего поиска, сложно идти дальше.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Январь 19, 2011, 15:18 »

Вот что я думаю. Если уж есть требование к высокоскорострельности алгоритма, то нужно знать чуть больше, чем просто список и порог для поиска. Как минимум хорошо было бы знать характер содержимого списка: частично сортирован(тенденция уменьшения/возрастания ключей слева-направо), максимальные значения ключей, размер списка... Возможно что-то еще понадобится.
Ну а на сколько я мог судить список частично сортирован. Поэтому искать надо с конца, где наименьшие значения. Но опять же, не зная принципа получения значения порога N во время текущего поиска, сложно идти дальше.
Выше уже говорилось откуда растут эти ноги  Улыбающийся  http://www.prog.org.ru/index.php?topic=16223.msg108905#msg108905

Порог N есть mAccessTotal (общее число обращений к кэшу), а ключ есть mAccessCount (член страницы, номер последнего к ней обращения)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.173 секунд. Запросов: 23.