![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Привет всем! Кто может подскажите! Проблема следующая:
Есть два файла dbf каждый примерно около 100 000 записей. Записи перегоняю в StringList, для каждого dbf свой StringList. Дальше сравниваю StringList-ы и по неким условиям пишу результат в другие StringList-ы. Работает очень медленно, примерно 2 500 записей обрабатываются 10 минут. Тормозит на этом цикле: Код:
// функция из dbf пишет в StringList
StrListSprEgkNew := WriteDbfInStringList(dirFileSprNew);
dirFileSprOld := FindDirForFileSpr(False);
StrListSprEgkOld := TStringList.Create;
// функция из dbf пишет в StringList
StrListSprEgkOld := WriteDbfInStringList(dirFileSprOld);
StrListSprEgkRez := TStringList.Create;
StrListSprEgkRezInvalid := TStringList.Create;
for iStrListSprEgkNew := 0 to StrListSprEgkNew.Count - 1 do
begin
markRez := 1; // метка писать в результирующий1 StringList
markRezInvalid := 0;// метка писать в результирующий2 StringList
codeEgkNew := strWord(StrListSprEgkNew[iStrListSprEgkNew],2,#9);
// функция StrWord(s,n,a) из строки s вырезает позицию n разделителя a
invalidNew := StrToInt(strWord(StrListSprEgkNew[iStrListSprEgkNew],4,#9));
for iStrListSprEgkOld := 0 to StrListSprEgkOld.Count - 1 do
begin
invalidOld := StrToInt(strWord(StrListSprEgkOld[iStrListSprEgkOld],4,#9));
codeEgkOld := strWord(StrListSprEgkOld[iStrListSprEgkOld],2,#9);
if codeEgkNew = codeEgkOld then
begin
markRez := 0;
if (invalidOld = 1) and (invalidNew = 0) then
begin
markRez := 1;
end;
if (invalidOld = 0) and (invalidNew = 1) then
begin
markRezInvalid := 1;
end;
end;
end;
if (markRez = 1) and (invalidNew = 0) then
begin
StrListSprEgkRez.Add(StrListSprEgkNew[iStrListSprEgkNew]);
end;
if markRezInvalid = 1 then
begin
StrListSprEgkRezInvalid.Add(StrListSprEgkNew[iStrListSprEgkNew]);
end;
Logger.Add(IntToStr(iStrListSprEgkNew));
end;подскажите как можно оптимизировать процесс? Последний раз редактировалось Admin, 27.09.2013 в 13:03. |
|
#2
|
||||
|
||||
|
Можно через ADO сделать выборку сразу из двух dbf`ок без всяких перегонов и т.д.
|
|
#3
|
|||
|
|||
|
Сделал через ADO вернее через TDbf получилось ещё медленнее, За 10 минут обработалось 279 записей.
|
|
#4
|
||||
|
||||
|
Тайм код говорит о том, что оптимизация нужна здесь: (68% времени на эту операцию уходит):
Код:
markRez := 0;
if (invalidOld = 1) and (invalidNew = 0) then
begin
markRez := 1;
end;
if (invalidOld = 0) and (invalidNew = 1) then
begin
markRezInvalid := 1;
end;Нужно заменить ваш блок на этот: Код:
markRez := InvalidOld AND not invalidNew; markRezInvalid := invalidNew AND not invalidOld; Я сомневаюсь, что Not нужен. На живом примере, через Debug нужно проверить значения переменных. B уничтожить к чертям сдвоенные if'ы Последний раз редактировалось Uniq!, 27.09.2013 в 14:47. |
| Этот пользователь сказал Спасибо Uniq! за это полезное сообщение: | ||
kasper_chib (27.09.2013)
| ||
|
#5
|
||||
|
||||
|
я так понимаю, вы берете запись из первого грида и сравниваете со всеми во втором...
это 100000*100000 = 10000000000 какое тз? |
|
#6
|
|||
|
|||
|
Для Mrak
Все правильно беру первый и сравниваю со вторым. Задание Нужно сравнивать два файла с справочником, сегодняшний и вчерашний. Найти 1. новые записи с полем invalid = 0 2. Старые записи где поле invalid было 1 стало 0 записать то что нашёл в *.txt 3. найти старые записи, где поле invalid было 0 стало 1 записать в другой *.txt Последний раз редактировалось kasper_chib, 27.09.2013 в 16:15. |
|
#7
|
||||
|
||||
|
Цитата:
гугли ADO + DBF |
| Этот пользователь сказал Спасибо Mrak за это полезное сообщение: | ||
kasper_chib (27.09.2013)
| ||