Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Возможно ли упростить код?


Автор: sokolik117845 18.4.2012, 23:02
Как упростить данный код? Жутко тормозит при обработке больших файлов!
Код

procedure TForm1.SortNumber;
var ts, ts1,ts2, ts3 :TStringList;
   i : integer;
   s : string;
begin
  ts := TStringList.Create;
  ts1 := TStringList.Create;
  ts2 := TStringList.Create;
  ts3 := TStringList.Create;

  try
    ts.LoadFromFile('Исходный.txt');
    progressbar1.Max:=ts.Count;
    for i:=0 to ts.Count-1 do begin
      s := ts.Strings[i];
      progressbar1.StepBy(1);
      Application.ProcessMessages;
    
      if  (Pos('+7903',s)=1)
      or  (Pos('+7905',s)=1)
      or  (Pos('+7906',s)=1)
      or  (Pos('+7909',s)=1)
      or  (Pos('+7960',s)=1)
      or  (Pos('+7961',s)=1)
      or  (Pos('+7962',s)=1)
      or  (Pos('+7963',s)=1)
      or  (Pos('+7964',s)=1)
      or  (Pos('+7965',s)=1)
      or  (Pos('+7967',s)=1)
      then ts1.Append(s)

      else
        if  (Pos('+7910',s)=1)
        or  (Pos('+7911',s)=1)
        or  (Pos('+7912',s)=1)
        or  (Pos('+7913',s)=1)
        or  (Pos('+7914',s)=1)
        or  (Pos('+7915',s)=1)
        or  (Pos('+7916',s)=1)
        or  (Pos('+7917',s)=1)
        or  (Pos('+7918',s)=1)
        or  (Pos('+7919',s)=1)
        or  (Pos('+7980',s)=1)
        or  (Pos('+7981',s)=1)
        or  (Pos('+7982',s)=1)
        or  (Pos('+7983',s)=1)
        or  (Pos('+7984',s)=1)
        or  (Pos('+7985',s)=1)
        or  (Pos('+7987',s)=1)
        or  (Pos('+7988',s)=1)
        or  (Pos('+7989',s)=1)
        then ts2.Append(s)

        else
          if  (Pos('+7920',s)=1)
          or  (Pos('+7921',s)=1)
          or  (Pos('+7922',s)=1)
          or  (Pos('+7923',s)=1)
          or  (Pos('+7924',s)=1)
          or  (Pos('+7925',s)=1)
          or  (Pos('+7926',s)=1)
          or  (Pos('+7927',s)=1)
          or  (Pos('+7928',s)=1)
          or  (Pos('+7929',s)=1)
          or  (Pos('+7930',s)=1)
          or  (Pos('+7931',s)=1)
          or  (Pos('+7932',s)=1)
          or  (Pos('+7933',s)=1)
          or  (Pos('+7934',s)=1)
          or  (Pos('+7936',s)=1)
          or  (Pos('+7937',s)=1)
          or  (Pos('+7938',s)=1)
          or  (Pos('+7939',s)=1)
          then ts3.Append(s)

     end;


     {сохранение результатов}

     ts1.SaveToFile('beeline.txt');
     ts2.SaveToFile('mts.txt');
     ts3.SaveToFile('megafon.txt');

  finally
     ts.Free;
     ts1.Free;
     ts2.Free;
     ts3.Free;
  end;
end;

Автор: Данкинг 18.4.2012, 23:12
Хранить данные в БД. Если же требуется работа именно с .txt, то логичней читать файл построчно через Assign...Readln, нежели грузить его целиком в стринглист.

Автор: kami 18.4.2012, 23:13
TStreamReader/TStreamWriter.

Автор: sokolik117845 18.4.2012, 23:14
Необходима работа именно с txt файлом, если не трудно киньте кто-нибудь код!

Автор: kami 18.4.2012, 23:27
Как-то так (без обработки ошибок):

Код

FSource:=TFileStream.Create('Исходный.txt', fmOpenRead);
FDestBee:=TFileStream.Create('bee.txt', fmCreate);

SR:=TStreamReader.Create(FSource);
SWbee:=TStreamWriter.Create(FDestBee);

While not SR.EndOfStream do
  begin
    str:=SR.ReadLine;
    if бла-бла бла then 
      SWbee.WriteLine(str);
  end;

SWbee.Free;
SR.Free;
FSource.Free;
FDest.Free;

Автор: sokolik117845 18.4.2012, 23:48
Если у кого еще есть варианты буду признателен!

Автор: Данкинг 19.4.2012, 00:08
Код

procedure Bugoga;
var pp:string;
 f1,f2:textfile;
begin
 assignfile(f1,'Исходный.txt');
 assignfile(f2,'Пчелайн.txt');
 reset(f1);
 rewrite(f2);
while not eof(f1) do
 begin
  readln(f1,pp);
   if бугога then
      writeln(f2,pp);
  end;
closefile(f1);
closefile(f2);
end;


Автор: northener 19.4.2012, 00:26
Цитата(Данкинг @  19.4.2012,  00:08 Найти цитируемый пост)
procedure Bugoga;

Не обижайтесь, но во-первых это ваше решение не соответствует задаче в топике. А во-вторых задаче не соответствует ваше высказывание 
Цитата

Если же требуется работа именно с .txt, то логичней читать файл построчно через Assign...Readln, нежели грузить его целиком в стринглист. 

Ведь в задаче требуется некий вариант сортировки/выбора из списка неких отдельных элементов с целью создать по некоему условию несколько новых списков. Мой исторически любимый метод доступа к текстовым файлам "Assign,Readln,Writeln" совершенно очевидно будет жестоко тормозить в отличие от методов чтения файла "целиком" с последующей обработкой строк в памяти.

А автору я посоветую учесть что Application.ProcessMessage конечно вещь хорошая и полезная. Но она в чём-то похожа на одеколон/духи. И то и другое хорошо в меру, а избыток и того и другого обычно портит жизнь всем.
И уж тем более задуматься на вопросом - зачем вызывать 
Код
progressbar1.StepBy(1)
 на каждой итерации цикла? При том что файлы большие а ширина экрана в пикселях маленькая (даже ну очень маленькая по сравнению с количеством строк в "больших" текстовых файлах). А ведь вызов progressbar1.StepBy(1) в сочетании с Application.ProcessMessage вызывает принудительную перерисовку на каждой итерации цикла! Вот и тормоза.

Автор: Данкинг 19.4.2012, 09:38
Цитата(northener @  19.4.2012,  01:26 Найти цитируемый пост)
Не обижайтесь, но во-первых это ваше решение не соответствует задаче в топике.

Почему это, не понял?
Цитата(northener @  19.4.2012,  01:26 Найти цитируемый пост)
Мой исторически любимый метод доступа к текстовым файлам "Assign,Readln,Writeln" совершенно очевидно будет жестоко тормозить в отличие от методов чтения файла "целиком" с последующей обработкой строк в памяти.

Тоже не понял. Т.е. построчное чтение будет тормозить? С какой стати? Я сам для подобного использую Assign...Read и ничего не тормозит, а уж тем более по сравнению, как если бы я в стринглист грузил.

Автор: Qu1nt 19.4.2012, 10:43
Для подобных задач нужно использовать data-driven подход. Достаточно префиксы телефонов сопоставить с номерами групп. Можно даже хранить эти ассоциации в файле, чтобы для добавления нового префикса или группы не было необходимости перекомпилировать код. Текущий подход с простынями однотипных проверок — частый гость на http://govnokod.ru/.
По поводу радостей вида AssignFile/CloseFile. Хватит. Остановитесь. Это из процедурного мира. Ну серьезно, сколько еще десятилетий должно пройти, чтобы этот подход вымер. Есть гораздо более удобные сущности TStreamReader/TStreamWriter и прочие.
Далее про Application.ProcessMessage. В большинстве случаев это очень грязный хак. И это именно тот случай. Ознакомьтесь с потоками — это путь развития правильного программиста.
И последнее. Если можно полностью не загружать файл в память, то нужно его не загружать. Вариант с TStringList несколько быстрее, но при достаточно большом размере исходного файла памяти просто не хватит.

Автор: Данкинг 19.4.2012, 11:13
Цитата(Qu1nt @  19.4.2012,  11:43 Найти цитируемый пост)
Ну серьезно, сколько еще десятилетий должно пройти, чтобы этот подход вымер. 

А зачем вымирать простым, наглядным и понятным операторам? smile 
Цитата(Qu1nt @  19.4.2012,  11:43 Найти цитируемый пост)
Есть гораздо более удобные сущности TStreamReader/TStreamWriter и прочие.

Кому как.

Автор: northener 20.4.2012, 00:41
Цитата(Qu1nt @  19.4.2012,  10:43 Найти цитируемый пост)
Далее про Application.ProcessMessage. В большинстве случаев это очень грязный хак. И это именно тот случай. Ознакомьтесь с потоками — это путь развития правильного программиста.

Вот тут уже я не соглашусь с таким категоричным суждением. Не стоит бездумно делать любое приложение многопоточным! Как, в прочем, вообще не стоит применять какой-то (любой) инструмент бездумно. А в случае автора доппоток скорее всего нафиг не нужен! Использовать Application.ProcessMessage - самое нормальное решение, только нужно им правильно воспользоваться.
И особенно я против советов типа "Ознакомьтесь с потоками — это путь развития правильного программиста." Сначала нужно ознакомиться с базовыми знаниями, а уж потом с "расширенными".

Цитата(Qu1nt @  19.4.2012,  10:43 Найти цитируемый пост)
Ну серьезно, сколько еще десятилетий должно пройти, чтобы этот подход вымер.

А тут во всём соглашусь с Данкигом. Простая обычная отвёртка никогда не умрёт несмотря ни на какие изобретения шуруповертов и спецотверток, которые позволяют работать не переставляя саму отвертку в новое положение.

Цитата(Данкинг @  19.4.2012,  09:38 Найти цитируемый пост)
Тоже не понял. Т.е. построчное чтение будет тормозить? С какой стати?

Вот тут имхо (которое я забыл указать в том своём посте). Файловые операции упираются в работу с физическим диском. Оптимизация чтения файла со стороны ОС вроде позволяет наиболее быстро считать файл целиком, нежели неопределенными кусками через неопределенные промежутки времени.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)