![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
У можно как-то у TList'a сделать эффектное массовое удаление? [D7, WinXP]
Aleksandr. © (2004-08-11 17:43:00)Тут у меня потомок 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;
TUser (2004-08-11 20:07:00) [1]TList использует массивы, а тебе нужны связные списки. Они для удаления/добавления лучше (в смысле быстреее).
Mim1 (2004-08-11 19:43:00) [2]Отнаследоваться от списка, добавть метод удаяющий несколько значений.
Можно сделать вообще процедурой чтобы ни от чего не наследоваться.
Исходники я бы править не взялся.
Aleksandr. (2004-08-11 19:10:00) [3]Mim1 © :
А какое Вам видится решение?
Aleksandr. (2004-08-11 19:05:00) [4]Ха-ха! Ну и бандарлог же я! Конечно, стартовый для смещения надо было задавать следующий от конечного индекса! Работает одним легким движением! Всем спасибо.
Mim1 (2004-08-11 19:05:00) [5]
> [20] VMcL © (11.08.04 18:32)
Действительно :), каюсь моя ошибка. Тогда решение проблеммы мне видется очень простым.
Aleksandr. (2004-08-11 18:59:00) [6]Ой млин... а там сурсом у Move не FList^[ToIndex], часом, надо?
Aleksandr. (2004-08-11 18:47:00) [7]В смысле, на один сдвиг между нулевым и первым происходит, а остальные на местах остаются.
Aleksandr. (2004-08-11 18:41:00) [8]Мастер © :
Так так я и сделал:
if ToIndex<FCount then
System.Move(FList^[FromIndex+1], FList^[FromIndex],
(FCount-ToIndex-1) * SizeOf(Pointer));
Dec(FCount,ToIndex-FromIndex+1)
Бесполезно. Элементы с FromIndex по ToIndex остаются на своих местах.
Мастер (2004-08-11 18:36:00) [9]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:34:00) [10]Мастер © :
Не получается подправить :(. Не мувится ничего.
VMcL (2004-08-11 18:32:00) [11]>> Mim1 © (11.08.04 18:09) [11]
AFAIR, TList.List никто не отменял.
Мастер (2004-08-11 18:29:00) [12]>Aleksandr. (11.08.04 18:26) [18]
Ну так подправь-)
>Mim1 © (11.08.04 18:22) [17]
СОгласен... В случае больших объемов будет заметно.
Aleksandr. (2004-08-11 18:26:00) [13]> Мастер © :
Посмотрите на условие. Move для данного случая выполняться не будет, потому что:
FCount=500000-300000+1 = 200001
300000>200000, а по условию
if Index2 < FCount then
все наоборот.
Mim1 (2004-08-11 18:22:00) [14]
> [14] Мастер © (11.08.04 18:12)
После удаления на место удаленного элемента копируются все элементы стоящие после удаляемого. В случае downto копируется меньшее количество. Количество удаляемых элементов влияет на скорость.
Мастер (2004-08-11 18:20:00) [15]>Aleksandr. (11.08.04 18:17) [15]
Выглядит красиво, но получается нестыковка:
Что за нестыковка?
Aleksandr. (2004-08-11 18:17:00) [16]> Мастер © :
Выглядит красиво, но получается нестыковка:
Если у меня 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:12:00) [17]>Mim1 © (11.08.04 18:12) [13]
Да
Какое?
Mim1 (2004-08-11 18:12:00) [18]
> [12] Мастер © (11.08.04 18:09)
Да
Мастер (2004-08-11 18:09:00) [19]>VMcL © (11.08.04 18:06) [10]
Удалять в порядке Count - 1 downto 0 пробовал?
А разве в данном случае это имеет значение?
Mim1 (2004-08-11 18:09:00) [20]
> [8] Aleksandr. (11.08.04 17:59)
Вы не имеете досиупа в наследнике в переменной предка FList поскольку она private. Так что прийдется написать свой TAlxList (путем вынесения едшые из модуля classes и добавления нужного метода), или прийдется пойти методом > [3]хотя с оброением к элементу по индексу будет проблемма.