Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Общие вопросы > Необходимо увеличить скорость работы функции |
Автор: mardoc 26.4.2011, 09:32 | ||
Есть рабочая функция удаления записей в массиве
Необходимо увеличить скорость работы функции. Так как при массивах более 10тыс записей становится мягко говоря не комфортно ![]() |
Автор: Snowy 26.4.2011, 10:15 |
Нужно просто SetLength вынести за пределы цикла. Вместо изменения размера, заведи переменную, куда сохраняй нужный размер. И уже по окончании цикла делай SetLength на нужный. Именно SetLength и кушает процессор. |
Автор: yahont7 26.4.2011, 14:15 | ||
Можно попробовать так:
|
Автор: mardoc 26.4.2011, 17:04 | ||
Спасибо за ответы . Сделал проще перенес setLength за цикл:
код работает быстрее, но все равно медленно. :( Дело в том, что операции move приходиться переносить большие блоки в памяти, массив большой очень, в нем хранятся много всего. У меня, возможно, неверный подход к решению задачи!. А задача такова: необходимо фильтровать данные в массиве (фильтр задает пользователь). Для меня идеал по скорости фильрации это EXCEL ![]() |
Автор: MetalFan 26.4.2011, 17:29 |
Отказаться от массива в пользу связанных списков. Там удаление будет делаться в разы быстрее) Ну или TList. |
Автор: Snowy 26.4.2011, 18:50 |
Перемещать нужно не сами записи, а указатели на них. Ну и раз уж массив нефиксированного размера, то действительно, для данной задачи больше подходят списки - TList и его потомки. |
Автор: mardoc 26.4.2011, 19:28 | ||
С TList не хочется заводится слишком много кода переписывать. :( Вот написал более-менее устраивающее решение (скорость раз в 100 быстрее), но у него есть свои минусы.
Добавлено @ 19:31 О, а можно пример ? ![]() |
Автор: yahont7 26.4.2011, 19:55 | ||||
При каждом вызове этой процедуры, старый указатель на ProdArr будет затиратся новым TempArr, что приведет к утечки памяти, ибо весь стары динамический массив ProdArr будет оставаться в памяти а переменная ProdArr будет содержать указатель на вновь созданный TempArr.. С каждым вызовом процедуры удаления, оперативка будет грузится на целый (старый) массив ProdArr. Потому в таком случае надо переиначить твой код след образом:
|
Автор: yahont7 26.4.2011, 20:24 | ||||||||
Проще перейти на использование TList. Но при этом придется Использовать запись в виде указателя.
Соответсвено изменится и правила доступа к массиву.. прежде чем туда записать новый элемент, нужно будет под этот элемент выделить память процедурой New (и при удалении элемента не забыть про процедуру Dispose)... Так или иначе а лучше запись TProductRecord объявить как класс (за одно туда можно и функционал навесить в виде процедур и функций). А в качестве массива использовать хранитель указателей - объект TList. Вот например как можно переписать запись:
Добавление нового элемента в список
Както так в упрощенном виде. |
Автор: mardoc 26.4.2011, 22:12 |
yahont7 Огромное спасибо за ответы. Реально помогли. Попробую использовать TList в своих проектах. |
Автор: imageman 2.5.2011, 21:13 |
я так понимаю, ты первоначально делал перемещение всех записей от текущей до конца, а потом перешел к перемещению одной записи в новый массив. Возможно будет несколько быстрее воспользоваться копированием? Для record можно просто использовать присвоение (по типу ProdArr[0]:=ProdArr[100]). Если размер одного элемента ProdArr большой, то копирование содержимого ProdArr будет вестись долго при любых ухищрениях и нужно, как подсказал yahont7, использовать указатели. В этом случае будет копироваться не xxx байт записи, а 4 байта указателя на запись. И в сторону СУБД можно посмотреть (как универсальном хранилище данных). |