Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
ВнизУ можно как-то у TList a сделать эффектное массовое удаление? Найти похожие ветки
← →
Aleksandr. (2004-08-11 17:43) [0]Тут у меня потомок TList работает, так вот при наборе в 500000 элементов удаляет он их достаточно медленно, если вызывать List.Delete(0). Смотрел я долго на всякие мувы, которые у него внутри происходят, но чего-то так ничего и не выцепил, как можно было бы одним обращением задать ему на удаление элементов так с тысячу:
procedure TList.Delete(Index: Integer);
var
Temp: Pointer;
begin
if (Index < 0) or (Index >= FCount) then
Error(@SListIndexError, Index);
Temp := Items[Index];
Dec(FCount);
if Index < FCount then
System.Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(Pointer));
if Temp <> nil then
Notify(Temp, lnDeleted);
end;
← →
Sandman25 © (2004-08-11 17:46) [1]Похоже, что выбрана неверная структура данных. Поподробнее о задаче можно?
← →
MacroDenS © (2004-08-11 17:47) [2]удаление процесс обратный добавлению!
Добавляешь построчно - удаляешь построчно...
← →
Ega23 © (2004-08-11 17:52) [3]Можно только посоветовать свой список создать.
Например: каждый элемент хранить в структуре "указатель на объект" + "указатель на следующий элемент".
При удалении k-го элемента "указатель на следующий элемент" в (k-1)-м элементе перенаправлять на (k+1)-й элемент.
Правда тогда поледний элемент будет долго удалять :о)
← →
Aleksandr. (2004-08-11 17:53) [4]Задача - превратить цикл
System.Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(Pointer));
в какое-то одно действие. Причем тут структура - освобождение тех же пятисот тысяч итемов перед удалением делается моментально. А вот на удалении тормоза.
← →
Sandman25 © (2004-08-11 17:55) [5][4] Aleksandr. (11.08.04 17:53)
После такого:
Причем тут структура
остается только спросить: "List.Clear не подойдет?"
← →
Sandman25 © (2004-08-11 17:58) [6]Напишите своего наследника TList, добавьте метод DeleteItems(FirstIndex, Count)
← →
Aleksandr. (2004-08-11 17:58) [7]Нет, потому что удаляются не все элементы.
← →
Aleksandr. (2004-08-11 17:59) [8]Ну, метод я добавил, но как его реализовать? Как массовый сдвиг сделать?
← →
Мастер © (2004-08-11 18:04) [9]Что-то такое примерно:
procedure TList.DeleteItems(Index1,Index2: Integer);
//var
// Temp: Pointer;
begin
if (Index1>Index2) or (Index1 < 0) or (Index2 >= FCount) then
Error(@SListIndexError, Index);
// Temp := Items[Index];
Dec(FCount,Index2-Index1+1);
if Index2 < FCount then
System.Move(FList^[Index1 + 1], FList^[Index1],
(FCount - Index2) * SizeOf(Pointer));
// if Temp <> nil then
// Notify(Temp, lnDeleted);
end;
Если необходимо, то можно переопределить TList.Notify
← →
VMcL © (2004-08-11 18:06) [10]>>Aleksandr. (11.08.04 17:43)
Удалять в порядке Count - 1 downto 0 пробовал?
← →
Mim1 © (2004-08-11 18:09) [11]
> [8] Aleksandr. (11.08.04 17:59)
Вы не имеете досиупа в наследнике в переменной предка FList поскольку она private. Так что прийдется написать свой TAlxList (путем вынесения едшые из модуля classes и добавления нужного метода), или прийдется пойти методом > [3] хотя с оброением к элементу по индексу будет проблемма.
← →
Мастер © (2004-08-11 18:09) [12]>VMcL © (11.08.04 18:06) [10]
Удалять в порядке Count - 1 downto 0 пробовал?
А разве в данном случае это имеет значение?
← →
Mim1 © (2004-08-11 18:12) [13]
> [12] Мастер © (11.08.04 18:09)
Да
← →
Мастер © (2004-08-11 18:12) [14]>Mim1 © (11.08.04 18:12) [13]
Да
Какое?
← →
Aleksandr. (2004-08-11 18:17) [15]> Мастер © :
Выглядит красиво, но получается нестыковка:
Если у меня 500000 элементов, мне надо удалить с нулевого по 30000-й, то Index2 заведомо будет больше Count.
procedure TList.DeleteItems(Index1,Index2: Integer);
begin
if (Index1>Index2) or (Index1 < 0) or (Index2 >= FCount) then
Error(@SListIndexError, Index);
Dec(FCount,Index2-Index1+1);
if Index2 < FCount then
System.Move(FList^[Index1 + 1], FList^[Index1],
(FCount - Index2) * SizeOf(Pointer));
end;
← →
Мастер © (2004-08-11 18:20) [16]>Aleksandr. (11.08.04 18:17) [15]
Выглядит красиво, но получается нестыковка:
Что за нестыковка?
← →
Mim1 © (2004-08-11 18:22) [17]
> [14] Мастер © (11.08.04 18:12)
После удаления на место удаленного элемента копируются все элементы стоящие после удаляемого. В случае downto копируется меньшее количество. Количество удаляемых элементов влияет на скорость.
← →
Aleksandr. (2004-08-11 18:26) [18]> Мастер © :
Посмотрите на условие. Move для данного случая выполняться не будет, потому что:
FCount=500000-300000+1 = 200001
300000>200000, а по условию
if Index2 < FCount then
все наоборот.
← →
Мастер © (2004-08-11 18:29) [19]>Aleksandr. (11.08.04 18:26) [18]
Ну так подправь-)
>Mim1 © (11.08.04 18:22) [17]
СОгласен... В случае больших объемов будет заметно.
← →
VMcL © (2004-08-11 18:32) [20]>>Mim1 © (11.08.04 18:09) [11]
AFAIR, TList.List никто не отменял.
← →
Aleksandr. (2004-08-11 18:34) [21]Мастер © :
Не получается подправить :(. Не мувится ничего.
← →
Мастер © (2004-08-11 18:36) [22]Aleksandr. (11.08.04 18:34) [21]
procedure TList.DeleteItems(Index1,Index2: Integer);
begin
if (Index1>Index2) or (Index1 < 0) or (Index2 >= FCount) then
Error(@SListIndexError, Index);
if Index2 < FCount then
System.Move(FList^[Index1 + 1], FList^[Index1],
(FCount - Index2-1) * SizeOf(Pointer));
Dec(FCount,Index2-Index1+1)
end;
;
А так?
← →
Aleksandr. (2004-08-11 18:41) [23]Мастер © :
Так так я и сделал:
if ToIndex<FCount then
System.Move(FList^[FromIndex+1], FList^[FromIndex],
(FCount-ToIndex-1) * SizeOf(Pointer));
Dec(FCount,ToIndex-FromIndex+1)
Бесполезно. Элементы с FromIndex по ToIndex остаются на своих местах.
← →
Aleksandr. (2004-08-11 18:47) [24]В смысле, на один сдвиг между нулевым и первым происходит, а остальные на местах остаются.
← →
Aleksandr. (2004-08-11 18:59) [25]Ой млин... а там сурсом у Move не FList^[ToIndex], часом, надо?
← →
Mim1 © (2004-08-11 19:05) [26]
> [20] VMcL © (11.08.04 18:32)
Действительно :), каюсь моя ошибка. Тогда решение проблеммы мне видется очень простым.
← →
Aleksandr. (2004-08-11 19:05) [27]Ха-ха! Ну и бандарлог же я! Конечно, стартовый для смещения надо было задавать следующий от конечного индекса! Работает одним легким движением! Всем спасибо.
← →
Aleksandr. (2004-08-11 19:10) [28]Mim1 © :
А какое Вам видится решение?
← →
Mim1 © (2004-08-11 19:43) [29]Отнаследоваться от списка, добавть метод удаяющий несколько значений.
Можно сделать вообще процедурой чтобы ни от чего не наследоваться.
Исходники я бы править не взялся.
← →
TUser © (2004-08-11 20:07) [30]TList использует массивы, а тебе нужны связные списки. Они для удаления/добавления лучше (в смысле быстреее).
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.042 c