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

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

Быстрое чтение файла [D5, Win95/98]


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

Кастуся ©   (2004-06-21 22:46:00) 

мастера, хелп!
обрабатываю файл "дедовским" методом: построчно читаю данные и со строкой делаю все необходимое.
Но не устраивает скорость. На P-I-133 файл в обрабатывает за . Можно ли увеличить скорость на стадии чтения? (Обработка прочитанной строки оптимизированна до максимума) Я знаю, использовать либо BlockRead либо TFileStream но там надо читать буферами, для этого надо знать где строка заканчивается. А можно как-нибудь построчно читать?
Хотел попробовать сл. код:

Start := Stream.Position;
End := Start;
Repeat

Stream.Read(Buffer^, 1024);
CRPos := FindCR(Buffer^);   { где FindCR возвращает 0..1023 для CR,
и 1024, если он не найден}
Inc(End, CRPos);
Until CRPos < 1024;
GetMem(MyPChar, End - Start);  { Здесь может быть +-1 -- мне лень сегодня проверять! }
Stream.Seek(Start);
Stream.Read(MyPChar^, End - Start)

но что такое FindCR?
В общем как тут быть. Дело срочное, хелп плиз!!!


Romkin   (2004-06-28 12:11:00) [1]

Вот, пожалуйста. Разбирайся, должно работать.
Понятно, Lines должны быть созданы до вызова процедуры...

type
 TAutoState = (auWaitIdent, auInIdent, auReadMsg);

const
 Ident: string = 'MESSAGE:';
 EndStrChars: set of char = [ #13,#10];
 ExceptChars: set of char = [' ']; //Строка без этих символов

procedure GetMsgStrings(const FileName: string; Lines: TStrings);
var
 F: file of char;
 auState: TAutoState;
 IdLen: Integer;
 IdPos: Integer;
 ch: char;
 MsgStr: string;
begin
 idLen := Length(Ident);
 MsgStr := '';
 assignFile(F, FileName);
 reset(F);
 try
   auState := auWaitIdent;
   while not EOF(F) do
   begin
     Read(F, ch);
     case auState of
       auWaitIdent: begin //Ждем 'MESSAGE:'
         if ch = Ident[1] then //первый символ, однако
         begin
           idPos := 1;
           auState := auInIdent;
           //На тот случай, если длина Ident = 1
           if idPos = idLen then  //Ident найден
             auState := auReadMsg;
         end;
       end;
       auInIdent: begin //Проверяем, однако, совпадение
         Inc(idPos);
         if (ch = Ident[idPos]) and (idPos = idLen) then
           auState := auReadMsg
         else
           if ch <> Ident[idPos] then //Это не ident
             auState := auWaitIdent;

         //увы, только одно состояние :(
         //На случай попадания MESMESSAGE: и тд
         if (ch = Ident[1]) and (auState <> auInIdent) then
         begin
           idPos := 1;
           auState := auInIdent;
         end;
       end;
       auReadMsg: begin
         if not (ch in EndStrChars) then //Конца строки нет
         begin
           if not (ch in ExceptChars) then //все, кроме пробела
             MsgStr := MsgStr + ch;
         end
         else
         begin
           auState := auWaitIdent;
           Lines.Add(MsgStr);
           MsgStr := '';
         end
       end;
     end; //case
   end; //while
 finally
   CloseFile(F);
 end;
end;


Romkin   (2004-06-28 11:23:00) [2]

Кастуся  (27.06.04 09:32) [80] Не все так просто :))
Надо полностью определить правила. Лучше бы реальный пример привел, на первый взгляд, твой случай решается детерминированным автоматом, а то, что ты с message привел - недетерминированным удобнее ;)
Впрочем, эскиз набросать могу. Итак, есть текстовый файл, процедура должна заполнить TStrings частями строк, идущими после 'MESSAGE:' и до конца строки, удалив пробелы. Символы между идентификатором и концом строки - любые.
Так пойдет? :)) Сейчас будет...


Anatoly Podgoretsky   (2004-06-27 11:56:00) [3]

Поток длеко не непрерывный, а разбит на строки.


Кастуся   (2004-06-27 09:55:00) [4]


> Romkin ©   (25.06.04 16:36) [78]

вся штука в том, как в этом непрерывном потоке найти идентификационную строку?
или ты предлагаешь считывать строки методом
while not eof(f) do
begin
 readln(f,st);
 if pos('MESSAGE',st)>0 then
  использовать конечный автомат
end;
так?


Кастуся   (2004-06-27 09:32:00) [5]

Снова чуть-чуть продолжим

> Romkin ©   (25.06.04 16:36) [78]

Если считывать файл побайтно, возникает проблема с определением положения троки идентификатора. Вот задача:
в общем случае есть в тексте сообщение вида:
MESSAGE: ## ## ##  ## ## ##;
Необходимо его идентифицировать и получить, то что находится вместо #. Вот. как это реализ с пом-ю конечн автомата?


Кастуся   (2004-06-25 18:39:00) [6]

классно конечно

Ладно всем спасибо!!!


Romkin   (2004-06-25 16:36:00) [7]

>А можно пару слов про "конечный автомат"? Что енто такое и с чем его едят?
НУ я же уже давал:
Romkin ©  (23.06.04 18:09) [31]
Основная идея простая: файл рассматривается как непрерывный поток байт, каждый из которых проходит через "фильтр", который реагирует на него изменением состояния (и данных). В результате - DelSpaces, например, вообще не нужна будет, реакция на пробел простая - continue :))


Fay   (2004-06-25 16:32:00) [8]

2Кастуся   (25.06.04 15:57) [75]

> А можно пару слов про "конечный автомат"? Что енто такое
> и с чем его едят?

Вам не стыдно, товарищ? Интернет забит подобной инфой. Да и институте не умалчивают 8)


Anatoly Podgoretsky   (2004-06-25 16:03:00) [9]

Они могли работать в крайнем ограниченом количестве случаев, в большинстве случаев должны приводить к ошибке, хорошо если не критической.


Кастуся   (2004-06-25 15:57:00) [10]


> Romkin ©   (25.06.04 11:29) [74]

Может тебе интересно, конечно, что у меня за задача, но, еаверное, ИМХО лень будет тебе что-нибудь делать. В принципе, из этой ветки я извлек для себя массу полезного, благодаря чему, скорость работы моего алгоритма увеличилась в несколько раз.

> почему бы просто не делать кусочную оптимизацию, а переписать
> все на конечный автомат?

А можно пару слов про "конечный автомат"? Что енто такое и с чем его едят?

Так что спасибо огромное всем за помощь!


> Anatoly Podgoretsky ©   (25.06.04 10:25) [73]

а асм коды чьи-то там все равно не работали!


Romkin   (2004-06-25 11:29:00) [11]

Упс... Все почистили. Зачем же красный карандаш, когда синего было достаточно?!

Кастуся  (24.06.04 17:12) [66] Да, именно определяет расход времени на разные функции. GPProfile, например. НАйти можно, достаточно поискать Delphi profiler ;)

И, кстати, почему бы просто не делать кусочную оптимизацию, а переписать все на конечный автомат? Уверяю, скорее всего быстрее, чем автомат ты вряд ли сделаешь.
И я уже пару раз просил дать постановку, а что собственно требуется-то? Улучшать код надо разумно, и, на мой взгляд, лезть в дебри ассемблера и проблемно-зависимой оптимизации кода надо в крайнем случае. Если скорость универсального короткого кода не устраивает, прежде всего надо посмотреть, нельзя ли сам алгоритм улучшить


Anatoly Podgoretsky   (2004-06-25 10:25:00) [12]

Неправильное использоние регистров, в результате могут быть выполнены недопустимые вещи, абсольтно любые и AV самое легкое что может произойти. Код абсолютно безграмотен, именно все приведеные с использование ассемблера.


Кастуся   (2004-06-25 10:08:00) [13]

Так чем?


Кастуся   (2004-06-24 22:01:00) [14]


> Anatoly Podgoretsky ©   (24.06.04 21:13) [70]
> Слушай не лез бы ты в ассемблер, который раз по счету приводишь
> грубый и чрезвычайно опасный код. Ты бы хоть раз прочитал
> справку про встроеный ассемблер и соглашения.

а чем приведённый код може быть опсаным?


Anatoly Podgoretsky   (2004-06-24 21:13:00) [15]

Слушай не лез бы ты в ассемблер, который раз по счету приводишь грубый и чрезвычайно опасный код. Ты бы хоть раз прочитал справку про встроеный ассемблер и соглашения.


  (2004-06-24 20:30:00) [16]

Удалено модератором
Примечание: Смени ник.


  (2004-06-24 19:21:00) [17]

Удалено модератором
Примечание: Смени ник


Кастуся   (2004-06-24 18:35:00) [18]

короче пробовал я StrToInt64 - медленно работает


Кастуся   (2004-06-24 17:12:00) [19]


> Romkin ©   (24.06.04 11:21) [50]
> ЛУчше посмотреть на другие участки программы...
> А еще лучше воспользоваться профилировщиком


А что такое профилировщикик? Это я так понимаю поределяет что сколько времени занимет в программе? Это какая-то программа и где её достать?


> Romkin ©   (24.06.04 11:28) [52]
> Кстати, насколько я понял, тебе значение строки не нужно?
> Тогда StrToInt64, но разбей строку на две половины - как
> раз влезет.

Я вот ут думаю, а будет ли это все быстрее работать, чем просто

HexSt:='0'+'1'+'2'+'3'+'4'+'5'+'6'+'7'+'8'+'9'+'a'+'b'+'c'+'d'+'e'+'f';
Bad:=not (LastDelimiter(HexSt,w0)=32);


Fay   (2004-06-24 14:31:00) [20]

Пляски с sz в SetActive - левые 8)


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

Наверх

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