Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как сократить время выполнения процедуры? [D7, XP]


Страницы:   1 2 3

Tatiana ©   (2006-02-04 21:59:00) 

Необходимо прочитать данные из *.txt файла. Данные структурированы. Проблема в том, что если количество строк большое (больше 10 000), то файл открывается недостаточно быстро. Каккие могут быть варианты, чтобы процедура выполнялась быстрее?


vovnuke   (2006-02-08 17:15:00) [21]

а что если с этой структурой работать с помощью ClientDataSet, а из него уже сохранять в файл?


Alex_C   (2006-02-08 17:08:00) [22]

Тебе уже ответили - тут выход один
ReadBlock и читать ну скачем по 64000 байта за раз.
Кстати недавно столкнулся с проблемой - надо было в базу переконвертировать текстовый фаил размером 19 мег. Так никакие TStringList.LoadFromFile и затем работа в памяти не помогли - очень долго, а вот читать как бинарный фаил блоками - наиболее быстро. Только по строкам прийдется тебе самому разбивать.


Tatiana   (2006-02-08 16:57:00) [23]

А кроме оптимизации кода, могут быть еще какие-нибудь варианты, чтобы заадча выполнялась быстрее. Дело в том, что ни один из вариантов, указанных выше, все равно по времени не отличается :(


Tatiana   (2006-02-06 16:14:00) [24]

Да, вы правы. Перед разделением строки я заменяю все разделители на пробелы, единственно, не меняю их количество, т.е. если было три табуляции, после выполнения функции они превращаются в три пробела.


Desdechado   (2006-02-06 10:52:00) [25]

основное время уходит не на чтение из файла, а на операции по разрезанию строк
подозреваю, что количество табуляций/пробелов и прочего между числами плавающее (для визуального выравнивания в файле)
тогда нужно их позаменять на нормальный разделитель одного формата (например, табуляцию) StringReplace, а уж после этого применять SplitString


Gero   (2006-02-05 23:43:00) [26]

> Насколько я понимаю "." и "," тоже относятся к Delimiter?

Delimiter передается аргументом в функцию и может быть каким угодно на твое усмотрение.


Tatiana   (2006-02-05 23:10:00) [27]

Насколько я понимаю "." и "," тоже относятся к Delimiter? Если так, то процедура не подходит, т.к. в строке есть числа в виде десятичных дробей. Процедура SplitString отделит целые части от десятичных, а мне нужно все число. Я права???


Gero   (2006-02-05 22:17:00) [28]

> begin...end ©   (05.02.06 22:09)

Да, согласен, спасибо :)
Код старый и сюда был бездумно скопирован )


begin...end   (2006-02-05 22:09:00) [29]

> Gero ©   (05.02.06 22:01) [14]

procedure SplitString(const Str: string; Delimiter: Char; Strings: TStrings);
begin
 Strings.Delimiter := Delimiter;
 Strings.DelimitedText := Str
end


Gero   (2006-02-05 22:01:00) [30]

procedure SplitString(const Str: string; Delimiter: Char; Strings: TStrings);
var
 s: string;
 Pos, Pos2: Integer;
begin
 Strings.BeginUpdate;
 try
   Strings.Clear;
   Pos := 1;
   for Pos2 := 1 to Length(Str) do begin
     if Str[Pos2] = Delimiter then begin
       s := Copy(Str, Pos, Pos2 - Pos);
       Strings.Add(s);
       Pos := Pos2 + 1;
     end;
   end;
   s := Copy(Str, Pos, Length(Str) - Pos + 1);
   Strings.Add(s);
 finally
   Strings.EndUpdate;
 end;
end;


(c) DMClient team

Функция заносит подстроки в строке, разделенные Delimiter в Strings.

Надеюсь, с чтением файла построчно проблем не возникнет.


Tatiana   (2006-02-05 21:35:00) [31]

Файл заранее обработан таким образом, что в нем только цифры и , может быть слова (Name,Discriptoin), шапки нет, цифры (в смысле, поля) м.б. разделены пробелом, либо табуляцией, строки - вводом.


Desdechado   (2006-02-05 21:17:00) [32]

> Структура строки в *.txt файле:
не виду структуры, вижу только, что туда записано
структура подразумевает еще и "как записано"
т.е. должен быть указан формат, чем разделены поля, чем разделены строки, есть ли "шапка" и т.п.


Tatiana   (2006-02-05 20:52:00) [33]

Структура строки в *.txt файле:
Name         X         Y           Z           Description,
где Name и Description – String, а X, Y, Z – числа, с которыми впоследствии будут производиться математические преобразования.

У меня есть три варианта процедуры чтения файла, но по времени выполнения они не отличаются.

procedure TPoints.ReadPoints(aFileName: String); var
   j: integer;
   s,St : String;
   Point: RPoint;
   F: TextFile;

begin
 try
   AssignFile(F, aFileName);
   Reset(F);
   While not(Eof(F)) do
     begin
       Readln(F, s);
       s := TrimLeft(s);
       s := TabToSpace(s);
       s := DotToDecSep(s);
       if s <> '' then
         begin
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Name := St;
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.X := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Y := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While  s[j] <> ' '  do
             begin
               if j > Length(s) then Break;
               St := St + s[j];
               j := j+1;
             end;
           Point.Z := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While j <= Length(s) do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Discription := St;
           AddPoint(Point);
         end;
     end;
 except on E:Exception do
   DoOnError (peReadError) ;
 end;
 CloseFile(F);
end;

procedure TPoints.ReadPoints(aFileName: String); var
   j, i: integer;
   s,St : String;
   Point: RPoint;
   List: TStringList;
begin
 try
   List := TStringList.Create;
   List.LoadFromFile(aFileName);
    i := 0;
   While i <= List.Count - 1 do
     begin
       s := List[i];
       s := TrimLeft(s);
       s := DotToDecSepSpace(s);
       if s <> '' then
         begin
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Name := St;
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.X := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While s[j] <> ' ' do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Y := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While  s[j] <> ' '  do
             begin
               if j > Length(s) then Break;
               St := St + s[j];
               j := j+1;
             end;
           Point.Z := StrToFloat(St);
           s := TrimLeft(RightStr(s, (Length(s)-Length(St))));
           St := '';
           j := 1;

           While j <= Length(s) do
             begin
               St := St + s[j];
               j := j+1;
             end;
           Point.Discription := St;
           AddPoint(Point);
         end;
      i:= i + 1
     end;
 except on E:Exception do
   DoOnError (peReadError) ;
 end;
 List.Free;
end;

procedure TPoints.ReadPoints(aFileName: String); var
   i : integer;
   s : String;
   Point: RPoint;
   List: TStringList;

begin
 try
   List := TStringList.Create;
   List.LoadFromFile(aFileName);
   i := 0;
   While i <= List.Count - 1 do
     begin
       s := List[i];
       s := Trim(s);
       s := DotToDecSepSpace(s);
       if s <> '' then
         begin
           Point.Name := LeftStr(s, Pos(' ', s) - 1);
           s := TrimLeft(RightStr(s, (Length(s)-Pos(' ', s))));

           Point.X := StrToFloat(LeftStr(s, Pos(' ', s) - 1));
           s := TrimLeft(RightStr(s, (Length(s)-Pos(' ', s))));

           Point.Y := StrToFloat(LeftStr(s, Pos(' ', s) - 1));
           s := TrimLeft(RightStr(s, (Length(s)-Pos(' ', s))));

           if Pos(' ', s) = 0 then
             Point.Z := StrToFloat(s)
           else
             begin
               Point.Z := StrToFloat(LeftStr(s, Pos(' ', s) - 1));
               s := TrimLeft(RightStr(s, (Length(s)-Pos(' ', s))));
               Point.Discription := s;
             end;

           AddPoint(Point);

           end;
           i:= i + 1
         end;

 except on E:Exception do
   DoOnError (peReadError) ;
 end;
 List.Free;
end;


Anatoly Podgoretsky   (2006-02-05 16:45:00) [34]

Объем менее одного мегабайта, любой метод загрузки будет мгновенный, хоть в StringList


Tatiana   (2006-02-05 16:14:00) [35]

подождите, не гадайте :) я как только смогу обязательно пошлю код и объясню подробнее.


Desdechado   (2006-02-05 15:45:00) [36]

> Данные структурированы
вот это самое интересное и самое неосвещенное место в вопросе.
и кода нет
гадаем дальше?


tesseract   (2006-02-05 15:43:00) [37]

tatiana - Использовать ReadBuffer, а файл открывать, как бинарный с собственным разбором CR/LF.


Gero   (2006-02-05 03:05:00) [38]

TStringList работает достаточно быстро.


PAVIA   (2006-02-05 02:56:00) [39]

Чтобы было быстро нужно загрузить файл в памить и там его разбирать. Проще всего через потоки TStream +F1.


Desdechado   (2006-02-04 22:51:00) [40]

написать быструю процедуру


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо