![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Быстрое чтение файла [D5, Win95/98]
Кастуся © (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?
В общем как тут быть. Дело срочное, хелп плиз!!!
Fay (2004-06-24 09:48:00) [41]2Кастуся (24.06.04 08:42) [41]
Сильно быстрее не получится. Не "стоит выделки".
Fay (2004-06-24 09:46:00) [42]2Кастуся (24.06.04 08:58) [42]
Правильно, нет. Но АП и не говорил, что нет - он сказал " нужен"
Кастуся (2004-06-24 08:58:00) [43]
> Anatoly Podgoretsky © (23.06.04 22:58) [39]
> Для конвертации такой строки нужен Int128
такового типа нет в Дельфи! Как быть?
Кастуся (2004-06-24 08:42:00) [44]
> Fay © (24.06.04 06:38) [40]
понимаю, что медленный, скажи как быстрее, чем предложил Romkin!
Fay (2004-06-24 06:38:00) [45]2Кастуся (23.06.04 22:28) [37]
Твой способ удаления пробелов в строке ДИКО медленный.
Сравни с [33] на 10000 символах.
Anatoly Podgoretsky (2004-06-23 22:58:00) [46]Для конвертации такой строки нужен Int128
Кастуся (2004-06-23 22:55:00) [47]
> Romkin © (23.06.04 19:41) [34]
> Можно и быстрее, но не намного.
Говори как. Для меня очень важна скорость.
> N := StrToInt64('$'+S);
строка 32-х символьная
и при попытке конвертации первой же такой строки возникает ошибка "not a valid integer value" Что делать?
Вот пример строки:
000E190E131002001104294188601618
Кастуся (2004-06-23 22:28:00) [48]> Anatoly Podgoretsky © (23.06.04 20:25) [36]
> Алгоритм очень неэффективный, постоянное перераспределение
> памяти
Это ты про мой?
> алгоритм приведенный Ромкином при определенных условиях
> даст ускорение на порядки
алгоритм удаления пробелов из строки? и при каких условиях
> обрабатывать весь громадный файл на один проход
т.е.?
Anatoly Podgoretsky (2004-06-23 20:25:00) [49]Кастуся (23.06.04 19:21) [32]
Алгоритм очень неэффективный, постоянное перераспределение памяти, алгоритм приведенный Ромкином при определенных условиях даст ускорение на порядки, например если обрабатывать весь громадный файл на один проход, но не на один порядок быстрее. Чем длиннее строка, тем быстрее, зависимость не линейная.
Anatoly Podgoretsky (2004-06-23 20:13:00) [50]StrToInt64
Romkin (2004-06-23 19:41:00) [51]тьфу, StrToInt('$'+S) разумеется
Romkin (2004-06-23 19:28:00) [52]Кастуся (23.06.04 19:21) [32]
1. Фиии.
StringReplace тоже не быстро...
function DelSpaces(const S: String):String;
var
I, k, len:Integer;
begin
len := Length(S);
SetLength(Result, len);
k := 0;
for I := 1 to len do
if S[I]<>' ' then
begin
inc(k);
Result[k] := S[I];
end;
SetLength(Result, k);
end;
Думаю, сойдет. Можно и быстрее, но не намного.
2. Если строка не более 16 символов, то
N := IntToStr('$'+S);
Преобразует, если не прет - даст исключение
Кастуся (2004-06-23 19:21:00) [53]Так, вот конкретно. Требуется две вещи:
1) есть ли втроенная процедура удаления из строки всех пробелов? Если нет, то как это можно наибыстрее реализовать? Моя реализация:
function DelSpaces(S:String):String;
var
I:Integer;
begin
Result:='';
for I:=1 to Length(S) do
if S[I]<>' ' then Result:=Result+S[I];
end;
2) нужна процедура проверки валидности символов в строке, а точнее надо проверить, являются ли все символы в строке "шестнадцатеричными", т.е. принадлежат['0'..'9','a'..'f']. Опять наибыстрым способом. Моя реализация:
Bad:=not (LastDelimiter(HexSt,w0)=32);
Romkin (2004-06-23 18:09:00) [54]ЭЭЭ. А нельзя ли получить формальную постановку? А то с кодом как-то разбираться не хочется.
Насколько я понял, тебе парсинг строки сделать надо? Это в общем случае решается конечным автоматом, который просто считывает весь файл непрерывным потоком. Однократно.
Как правило, это быстрее всего. А вот какой автомат должен быть - это надо выбирать...
http://rsdn.ru/article/alg/statemachine.xml
Кастуся (2004-06-23 17:52:00) [55]
> а не программа управления ядерным реактором,
а если именно эта программа?
Кастуся (2004-06-23 17:51:00) [56]
> Sandman25 © (23.06.04 16:18) [26]
Знаешь ли ты английский язык?
Нет?
Вот чт написано в хелпе:
function LastDelimiter(const Delimiters, S: string): Integer;
Returns the byte index in S of the last character that matches any character in the Delimiters AnsiString.
Call LastDelimiter to locate the last delimiter in S. For example, the line
MyIndex := LastDelimiter('\.:','c:\filename.ext');
sets MyIndex to 12.
Перевожу:
function LastDelimiter(const Delimiters, S: string): Integer;
Возвращает индекс последнего символа строки S, который совпадает с любым из символов в строке Delimiters.
Используйте LastDelimiter для определения позиции последнего совпадающего символа. Например, строка
MyIndex := LastDelimiter('\.:','c:\filename.ext');
устанавливает значение MyIndex равным 12.
Даже пример есть, хоть по примеру можно догодацца-то! No comments...
Sandman25 (2004-06-23 17:04:00) [57][27] Кастуся (23.06.04 17:03)
От задачи зависит. Если это лабораторная, а не программа управления ядерным реактором, то можно не проверять.
Кастуся (2004-06-23 17:03:00) [58]Sandman25 © (23.06.04 16:18) [26]
а как тогда быть?
Sandman25 (2004-06-23 16:18:00) [59]Почитайте описание LastDelimiter.
Если захотите проверять каждый символ, скорость чтения файла упадет примерно в 30 раз....
Кастуся (2004-06-23 16:14:00) [60]мне надо чтобы вся строка состояла из ['0'..'9','a'..'f'] а не только последняя "буква"(w0[32])! Или я что-то не понимаю?