Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.09.2013, 12:44
kasper_chib kasper_chib вне форума
Прохожий
 
Регистрация: 26.09.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
Сообщение Привет всем! Оптимизировать!

Привет всем! Кто может подскажите! Проблема следующая:
Есть два файла 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  
Старый 27.09.2013, 13:06
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Можно через ADO сделать выборку сразу из двух dbf`ок без всяких перегонов и т.д.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 27.09.2013, 14:36
kasper_chib kasper_chib вне форума
Прохожий
 
Регистрация: 26.09.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Сделал через ADO вернее через TDbf получилось ещё медленнее, За 10 минут обработалось 279 записей.
Ответить с цитированием
  #4  
Старый 27.09.2013, 14:44
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Тайм код говорит о том, что оптимизация нужна здесь: (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;
Только они(markRez, markRezInvalid) тогда должны быть не 0 и 1 (int) а true и false (bool)
Я сомневаюсь, что Not нужен. На живом примере, через Debug нужно проверить значения переменных.



B уничтожить к чертям сдвоенные if'ы

Последний раз редактировалось Uniq!, 27.09.2013 в 14:47.
Ответить с цитированием
Этот пользователь сказал Спасибо Uniq! за это полезное сообщение:
kasper_chib (27.09.2013)
  #5  
Старый 27.09.2013, 14:46
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

я так понимаю, вы берете запись из первого грида и сравниваете со всеми во втором...
это 100000*100000 = 10000000000

какое тз?
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
  #6  
Старый 27.09.2013, 15:06
kasper_chib kasper_chib вне форума
Прохожий
 
Регистрация: 26.09.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Для Mrak

Все правильно беру первый и сравниваю со вторым.
Задание
Нужно сравнивать два файла с справочником, сегодняшний и вчерашний.
Найти
1. новые записи с полем invalid = 0
2. Старые записи где поле invalid было 1 стало 0
записать то что нашёл в *.txt
3. найти старые записи, где поле invalid было 0 стало 1
записать в другой *.txt

Последний раз редактировалось kasper_chib, 27.09.2013 в 16:15.
Ответить с цитированием
  #7  
Старый 27.09.2013, 15:12
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Можно через ADO сделать выборку сразу из двух dbf`ок без всяких перегонов и т.д.
используй механизм ADO

гугли ADO + DBF
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
kasper_chib (27.09.2013)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:51.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter