Все доброго времени суток, не могли бы вы помочь оптимизировать работу следующей процедуры:
procedure TForm1.Button3Click(Sender: TObject);
var L1,L2,L3:TStringList;
D1:TOpenDialog;
n1:string;
i:integer;
begin
L1:=TStringList.Create; //создание 1го стринглиста
L2:=TStringList.Create; //создание 2го стринглиста
L3:=TStringList.Create; //создание 3го стринглиста
D1:=TOpenDialog.Create(self);
if D1.Execute then n1:=D1.Filename else exit;
L1.LoadFromFile(n1);
if D1.Execute then L2.LoadFromFile(D1.Filename) else exit;
for i:=0 to L1.Count-1 do
if L2.IndexOf(L1[i])=-1 then L3.Add(L1[i]);
L3.SaveToFile('3.txt');
D1.Free;L1.Free; L2.Free; L3.Free;
end;
Я бы первым делом проверил время выполнения при отсортированном списке (в этом случае при IndexOf используется умный алгоритм поиска, а не обычный перебор). Т. е. добавьте "L2.Sorted := True". Если результат не устроит, то экспериментируйте дальше. Например, попробуйте для L2 вместо TStringList использовать хеш-таблицу TDictionary и метод ContainsKey.
А еще у вас утечки памяти. В случае exit объекты не уничтожаются. Используйте try и finally.
Псевдокод если сначала дублировать в список:
L3 = L1.clone
for line in L3
if line not in L2
L3.remove line
endif
endfor
L3.savetofile '3.txt'
for line in L1
if line not in L2
line.append_to_file '3.txt'
endif
endfor
L2_hash = {
'900150983cd24fb0d6963f7d28e17f72' = 'abc',
'4ed9407630eb1000c0f6b63842defa7d' = 'def',
'826bbc5d0522f5f20a1da4b60fa8c871' = 'ghi'
}
if L2_hash[md5(some_string)]
// строка содержится
endif
L2_hash = {
'900150983cd24fb0d6963f7d28e17f72' = 1,
'4ed9407630eb1000c0f6b63842defa7d' = 1,
'826bbc5d0522f5f20a1da4b60fa8c871' = 1
}
Мой вам совет - не используйте TStringList для обработки больших объемов данных. Лучше в простые массивы строк загрузите ваши файлы и далее можете таким же перебором их обойти. Результат будет заметен невооруженным глазом, говорю это из своего опыта.
List1.Sorted := True;
List2.Sorted := True;
Index1 := 0;
Index2 := 0;
while (Index1 < List1.Count - 1) and (Index2 < List1.Count - 1) do
begin
Cmp := CompareStrings(List1[Index1],
List2[Index2]);
if Cmp = 0 then Inc(Index1);
if Cmp > 0 then Inc(Index2);
if Cmp < 0 then
begin
List3.Add(List1[Index1]);
Inc(Index1);
end;
end;