Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
ВнизКак оптимизировать работу с типизированным файлом? Найти похожие ветки
← →
ИМХО (2004-01-16 07:55) [0]Имеется файл записей (каждая запись - по 16 байтов).
Размер файла - 694 720 байтов, то есть всего лишь 43 420 записей.
На старте программы я загружаю его (проходясь по всем записям), и программа застывает (то есть она обрабатывает его так долго).
Есть мысль, что AssignFile + Reset + BlockRead - очень неэффективны в данной ситуации :(
Есть ли способ оптимизировать работу?
← →
MBo (2004-01-16 08:03) [1]Всего 700K - проще считать все сразу в блок памяти, и работать как с массивом.
← →
ИМХО (2004-01-16 08:55) [2]MBo, подскажите, пожалуйста, на примере, как это осуществить.
← →
Anatoly Podgoretsky (2004-01-16 09:01) [3]BlockRead(F, ar, 694720);
← →
SSergey (2004-01-16 09:52) [4]А потом можешь читать записи уже не из файла а из блока памяти <ar> с помощью:
var R : TMyRecord;// где R - твоя запись размером 16 байт
begin
...
Move(ar, R, SizeOf(R))
← →
ИМХО (2004-01-16 10:38) [5]ПРОБЛЕМА ОСТАЛАСЬ!
Да, работать стало быстрее, но программа грузится несколько минут (!)
Перешел уже на TFileStream - не помогает :(
Объявляю:
var
MyStream: TFileStream;
Def: array of TDef; // запись 16 байтов
I: Integer;
Num_Rec: Integer;
MyStream := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone);
try
Num_Rec := MyStream.Size div 16;
SetLength(Def, Num_Rec);
MyStream.Read(Def, MyStream.Size);
for I := 0 to Num_Rec - 1 do
begin
...........
end;
finally
MyStream.Free;
end;
И все это хозяйство работает жутко долго :(
Есть ли еще способ оптимизировать загрузку этих злосчастных 43 420 записей?
← →
Тимохов (2004-01-16 10:40) [6]ИМХО © (16.01.04 10:38) [5]
Мне кажется - ошибка в 17 строке.
Не может 700 кб грузиться несколько минут.
Ошибка в неведомых нам частах твоего алгоритма.
← →
ИМХО (2004-01-16 10:43) [7]Зуб даю, грузится так долго, что хоть за смертью посылай!
← →
Тимохов (2004-01-16 10:51) [8]На какой строке тормозит?
Может в цикле?
← →
Семен Сорокин (2004-01-16 10:53) [9]ИМХО © (16.01.04 10:43) [7]
Зуб даю, грузится так долго, что хоть за смертью посылай!
нет ты все-таки глянь, может это обработка тормозит, у меня файлы по 15 метров через FileStream секунды обрабатываются.
← →
MBo (2004-01-16 10:55) [10]MyStream.Read(Def [0], MyStream.Size);
← →
ALEIIIKA (2004-01-16 10:56) [11]На какой машине сидишь, не бывает такой долгой загрузки 600 Кб. У меня 24 Мб текстового файла с преобразованием длится всего секунд 30.
Или давай весь исходник?
← →
alex_*** (2004-01-16 10:56) [12]через TMemoryStream.LoadFromFile() не пробовал?
← →
Anatoly Podgoretsky (2004-01-16 10:58) [13]Зачем же ты опять перешел на циклы, сказано читать сразу весь блок. TFileRead вполне удобный для этого компонент, и если ты не уложишься в 0,5-2 секунды ищи в другом месте, значит у тебя серьезные проблемы где то там.
← →
Семен Сорокин (2004-01-16 10:58) [14]2ИМХО
эх быть тебе беззубым :))
← →
ИМХО (2004-01-16 10:59) [15]Я понимаю, что мой K6-2, 450 - это не последнее слово в вычислительной технике, однако...
УБРАЛ УЖЕ ВСЁ, осталось только:
var
MyStream: TFileStream;
Def: array of TDef; // запись 16 байтов
I: Integer;
Num_Rec: Integer;
MyStream := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone);
try
Num_Rec := MyStream.Size div 16;
SetLength(Def, Num_Rec);
MyStream.Read(Def, MyStream.Size);
for I := 0 to Num_Rec - 1 do
begin
CurrentLabel.Caption := IntToStr(I + 1);
Application.ProcessMessages;
end;
finally
MyStream.Free;
end;
ДВЕ МИНУТЫ!
Я балдею с этой скорости.
← →
Anatoly Podgoretsky (2004-01-16 10:59) [16]Нет только без одного зуба, он предусмотрительный.
← →
ALEIIIKA (2004-01-16 11:00) [17]Кинь на мыло файл, посмотрим,чего можно сделать.
← →
Тимохов (2004-01-16 11:01) [18]Прислушайтся к MBo © (16.01.04 10:55) [10]
Скорее всего он прав - не уверен, сам с этими дин. массивами всегда копаюсь.
Сделай так:
1. Убери цикл
2. Запусти готовый ехе не из дельфи.
← →
Тимохов (2004-01-16 11:02) [19]Вообще Application.ProcessMessages; штука достаточно медленная
← →
ИМХО (2004-01-16 11:05) [20]Я не могу убрать цикл, мне нужно пройтись по всем записям и изъять оттуда кое-что.
← →
Тимохов (2004-01-16 11:06) [21]ИМХО © (16.01.04 11:05) [20]
1. Вот это кое-что и интересно бы посмотреть\
2. см [19]
← →
ИМХО (2004-01-16 11:06) [22]
> Anatoly Podgoretsky © (16.01.04 10:58) [13]
> Зачем же ты опять перешел на циклы, сказано читать сразу
> весь блок. TFileRead вполне удобный для этого компонент,
Что за компонент?
← →
Плохиш_ (2004-01-16 11:07) [23]>ИМХО © (16.01.04 11:05) [20]
Ну а ProcessMessages тебе зачем?
← →
Семен Сорокин (2004-01-16 11:08) [24]это что-ж 43420 раз ты хочешь отрисовать Label на форме?
CurrentLabel.Caption := IntToStr(I + 1);
Application.ProcessMessages;
неужто заметишь? :)
← →
alex_*** (2004-01-16 11:08) [25]Зачем тебе обнвлять Label так быстро? Все равно не успеет никто углядеть. Обновляй каждую сотню хотя бы. И обновляй только Label:
CurrentLabel.Refresh;
← →
ИМХО (2004-01-16 11:08) [26]
> MBo © (16.01.04 10:55) [10]
> MyStream.Read(Def[0], MyStream.Size);
Исправил, не помогло.
← →
Тимохов (2004-01-16 11:08) [27]ИМХО © (16.01.04 11:06) [22]
Зуб даю (твой :))) что проблем с чтением у тебя нет. Читай ты хоть чем проблема не в этом.
Все-таки запустить из exe - часто помогает.
← →
MBo (2004-01-16 11:08) [28]> for I := 0 to Num_Rec - 1 do
> begin
> CurrentLabel.Caption := IntToStr(I + 1);
> Application.ProcessMessages;
> end;
издеваешься????
Для чего тебе 40 тысяч раз метку обновлять???
И исправление [10] примени
← →
Anatoly Podgoretsky (2004-01-16 11:11) [29]ИМХО © (16.01.04 11:06) [22]
TFileStream
← →
Anatoly Podgoretsky (2004-01-16 11:15) [30]Цикл, абсолютно лишний, посольку ничего кроме паузы не делает, можно полностью удалить
for I := 0 to Num_Rec - 1 do
begin
CurrentLabel.Caption := IntToStr(I + 1);
Application.ProcessMessages;
end;
← →
ИМХО (2004-01-16 11:17) [31]Нет, цикл я убрать не могу, метку реже обновлять могу, а цикл - нельзя трогать, иначе загрузка бессмысленна.
← →
Тимохов (2004-01-16 11:18) [32]ИМХО © (16.01.04 11:17) [31]
Знаешь, это уже упрамство.
Превое что сделай (это кто-то уже выше говорил) делай в цикле так
if I mod 1000 = 0 then Application.ProcessMessages.
Получится обязательно
← →
Тимохов (2004-01-16 11:20) [33]Обновление метки в if из 32 засунь также
← →
Семен Сорокин (2004-01-16 11:20) [34]ИМХО © (16.01.04 11:17) [31]
Нет, цикл я убрать не могу, метку реже обновлять могу, а цикл - нельзя трогать, иначе загрузка бессмысленна.
но зуб отдать придется :)))
← →
Alexander666 (2004-01-16 11:31) [35]Уж сделай тогда, типа, "Ждите, идет загрузка... осталось недолго", и юзер поверит!
← →
Anatoly Podgoretsky (2004-01-16 11:33) [36]ИМХО © (16.01.04 11:17) [31]
Файл уже загружен! Перед строчкой for, полностью!
Цикл кроме паузы ничего не делает.
← →
ALEIIIKA (2004-01-16 11:41) [37]Молодец Anatoly Podgoretsky ©, понял где собака зарыта, а мы как самые умные советы даем, ужас какой.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.008 c