Название: Ускорить поиск в списке Отправлено: Igors от Сентябрь 08, 2011, 21:29 Добрый вечер
Переделываю/обновляю код написанный очень давно (и не мной) на С (практически). Программист использовал список, для простоты Код Конечно то же самое с std::list - не суть Профайлер показывает что тормозит на таком участке Код Lookup просматривает элементы начиная с theHead, пока не найдет с нужным ID. Откуда тормоза понятно. Легко сказать "возьми что-то другое вместо списка" - но во-первых это совсем непросто (код велик), а главное - здесь список прекрасно себя оправдывает во многих др. местах (удаления, перелинковки и.т.п) "Глубина поиска" не превышает 500 (хотя весь список может быть намного больше). Как бы мне здесь "ускориться" ? Спасибо Название: Re: Ускорить поиск в списке Отправлено: kambala от Сентябрь 08, 2011, 22:11 можно дополнительно завести словарь, ключами которого будут идентификаторы, а значениями - указатели на элементы списка. но тогда придется немного модифицировать функции по работе со списком для корректного обновления элементов словаря.
Название: Re: Ускорить поиск в списке Отправлено: SimpleSunny от Сентябрь 08, 2011, 23:20 А список можно отсортировать?
Тогда можно было бы хранить каждый n-ый элемент списка в дереве\векторе. И от него уже искать вперед\назад по списку. Название: Re: Ускорить поиск в списке Отправлено: Igors от Сентябрь 09, 2011, 01:48 можно дополнительно завести словарь, ключами которого будут идентификаторы, а значениями - указатели на элементы списка. но тогда придется немного модифицировать функции по работе со списком для корректного обновления элементов словаря. Прелесть списка в том что элемент часто "самодостаточен", т.е. его можно удалить из списка совсем не зная "голову", также и вставить. А словарь(и) надо где-то поселить и в каждый вызов как-то добавить - а их много сотен. А список можно отсортировать? Нет, сортировать исходный список нельзя, в нем порядок следования элементов определяет иерархиюТогда можно было бы хранить каждый n-ый элемент списка в дереве\векторе. И от него уже искать вперед\назад по списку. Название: Re: Ускорить поиск в списке Отправлено: LisandreL от Сентябрь 09, 2011, 06:58 Код: ... // используем данные data1 Название: Re: Ускорить поиск в списке Отправлено: Drafter от Сентябрь 09, 2011, 08:44 Мне кажется, вы хотите чего-то несбыточного. Если список нельзя ни сортировать, ни индексировать (тем или иным способом), то и про ускорение поиска мечтать нечего. Как говорится, нету ручек - нет варенья.
Название: Re: Ускорить поиск в списке Отправлено: LisandreL от Сентябрь 09, 2011, 08:54 Если список нельзя индексировать (тем или иным способом), то и про ускорение поиска мечтать нечего. Ну строго говоря кроме индексирования может помочь ещё распараллеливание поиска (на многоядерной машине), но для списка это тоже нетривиальное действо.Название: Re: Ускорить поиск в списке Отправлено: brankovic от Сентябрь 09, 2011, 08:58 Модификация списка тут есть? Иначе можно пробежаться 1 раз по списку и построить хеш. А потом доступ иметь по нему. А при чём тут модификация? Можно просто хранить рядом hash_map <long, CObject*>, вставлять в него на вставке в список, удалять при удалении из списка. А распараллеливание это очень сложная переделка, ТС даже в другой контейнер ленится перекладывать.. Название: Re: Ускорить поиск в списке Отправлено: kambala от Сентябрь 09, 2011, 11:24 Можно просто хранить рядом hash_map <long, CObject*>, вставлять в него на вставке в список, удалять при удалении из списка. можно дополнительно завести словарь, ключами которого будут идентификаторы, а значениями - указатели на элементы списка. но тогда придется немного модифицировать функции по работе со списком для корректного обновления элементов словаря. Прелесть списка в том что элемент часто "самодостаточен", т.е. его можно удалить из списка совсем не зная "голову", также и вставить. А словарь(и) надо где-то поселить и в каждый вызов как-то добавить - а их много сотен. а самих функций по работе со списком (типа Lookup()) много? или они доступны только через библиотеку? Название: Re: Ускорить поиск в списке Отправлено: Igors от Сентябрь 09, 2011, 12:51 а самих функций по работе со списком (типа Lookup()) много? или они доступны только через библиотеку? "Много" не то слово :) Я не могу даже проконтролировать сколькоА при чём тут модификация? Можно просто хранить рядом hash_map <long, CObject*>, вставлять в него на вставке в список, удалять при удалении из списка. А где "рядом"? И как (хотя бы "в каком направлении") менять массу ф-ций заточенных на список? Например, ф-ция перебрасывает элементы их одного списка в другойКод Это работает быстро и написать это легко. Втулить сюда хеш - и будет уже недешево и не быстро. А при интенсивной перелинковке я могу попасть "из огня да в полымя" Модификация списка тут есть? Иначе можно пробежаться 1 раз по списку и построить хеш. А потом доступ иметь по нему. Нет, модификации (здесь) нет. Но хеш получается медленнее чем прямой поиск. Почему: во-первых начинается malloc/free (которых прямой поиск не имеет не смотря на всю свою тупость). А во-вторых, число хешируемых элементов получается намного больше чем извлекаемых. Конкретно: 20-25 элементов ищутся по ID, максимальная глубина просмотра списка не превышает 500 (а для многих всего 10-20). Это не такой уж тормоз сам по себе - просто это место попадает на хороший цикл Название: Re: Ускорить поиск в списке Отправлено: brankovic от Сентябрь 09, 2011, 13:58 ...Можно просто хранить рядом hash_map <long, CObject*>, вставлять в него на вставке в список, удалять при удалении из списка. А где "рядом"? И как (хотя бы "в каком направлении") менять массу ф-ций заточенных на список?например одной глобальной переменной, т.е. общий хэш на все списки, можно так по задаче? Например, ф-ция перебрасывает элементы их одного списка в другой.. если можно общий хэш, то в этой функции перекладывать из хэша в хэш не понадобится. Если нет, то будем дальше думать :) Название: Re: Ускорить поиск в списке Отправлено: LisandreL от Сентябрь 09, 2011, 14:11 Это не такой уж тормоз сам по себе - просто это место попадает на хороший цикл Ну так вне этого цикла хеш построить нельзя?Название: Re: Ускорить поиск в списке Отправлено: Igors от Сентябрь 09, 2011, 14:17 например одной глобальной переменной, т.е. общий хэш на все списки, можно так по задаче? Нет. Есть 3D объекты, у каждого есть много чего, ну напр. текстуры (картинки). Они связаны в список, 3D объект хранит голову этого списка. ID текстуры будет уникально в пределах 3D объекта - но не во всем проекте. Со многими др данными аналогично. Решение использовать списки вполне оправдано - в большинстве случаев число элементов мало (ну сколько там тех текстур на 1 объекте - ну десятка 2 отсилы). Однако по мере разрастания задачи рос и объем некоторых списков - и вот это начало неприятно беспокоить.Ну так вне этого цикла хеш построить нельзя? Пользователь создал 4К объектов (простых кубиков). У каждого кубика свой список. Жалуется - рисует медленно. Смотрю профайлером - а там OpenGL отдыхает, 90% съедается на списках. Название: Re: Ускорить поиск в списке Отправлено: brankovic от Сентябрь 09, 2011, 14:43 ID текстуры будет уникально в пределах 3D объекта - но не во всем проекте. 1. когда вы ищите элемент с данным ID, вы точно знаете, что он там есть? 2. id в рамках объекта начинаются с 0 и идут подряд? Название: Re: Ускорить поиск в списке Отправлено: popper от Сентябрь 09, 2011, 14:49 Если список большой, а извлекать из него нужно намного меньшее количество элементов, то, возможно, будет быстрее осуществлять поиск по массиву ID объектов, данные которых требуется обработать. Т.е. модифицировать Lookup примерно следующим образом:
Код
вызов функции делать 1 раз Название: Re: Ускорить поиск в списке Отправлено: Igors от Сентябрь 10, 2011, 05:32 1. когда вы ищите элемент с данным ID, вы точно знаете, что он там есть? Да2. id в рамках объекта начинаются с 0 и идут подряд? Нет. В данном конкретном случае ID лежат в диапазоне [2000..5000](мои мысли читаете :)) Если список большой, а извлекать из него нужно намного меньшее количество элементов, то, возможно, будет быстрее осуществлять поиск по массиву ID объектов, данные которых требуется обработать. Т.е. модифицировать Lookup примерно следующим образом: 1) ОписАлись и подали вектора по значению. Исправьте чтобы не конфузить начинающихКод
2) push_back не годится, т.к. данные в списке могут идти в любом порядке. Лучше distance и присваивание 3) Вариант лучше прямолинейного хеширования, т.к. оперирует только с небольшим числом "извлекаемых" данных. Но все же недостаточно быстр (создание/удаление 2 векторов, find, потом еше 1 find) 4) Использование неудобно - мне сначала нужно как-то собрать вектор neededID и это должно рихтоваться всякий раз когда понадобится извлечь новое данное. Можно сделать намного быстрее используя статические массивы вместо векторов - но тогда использование станет еще менее удобным Название: Re: Ускорить поиск в списке Отправлено: popper от Сентябрь 10, 2011, 12:38 исправил на передачу векторов по ссылке
возможно, использование статических массивов - это наиболее эффективный способ ускориться, но со всеми вытекающими проблемами в использовании приведенный Вами код с последовательным вызовом Lookup для разных ID тоже в некотором смысле статический Название: Re: Ускорить поиск в списке Отправлено: Igors от Сентябрь 10, 2011, 16:10 возможно, использование статических массивов - это наиболее эффективный способ ускориться, но со всеми вытекающими проблемами в использовании Есть вариантик получше (без find) :) |