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

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

Долгое копирование потока. Как решить? [D6, WinXP]


beglec ©   (2006-01-09 10:28:00) 

Есть ли функция (альтернатива) значительно увеличивающая работу Stream.CopyFrom;

var StreamTmp,StreamFull: TMemoryStream;
...
While 0 to 10 do
begin
  StreamTmp.Clear;                              
  StreamTmp.LoadFromFile(NameFiles);            
  StreamFull.CopyFrom(StreamTmp,StreamTmp.Size); <- данный код работает очень медленно
end;
обработка данных
...

Загружается 10 файлов через поток и соединяются в 1 большой поток, после чего обрабатываются в одном цикле.

Сделал два варианта.
1. Вариант который указан выше. Очень удобно, но медленно работает CopyFrom - копирование потока в другой поток. (обработка всей инфы 30 сек);
2. Вариант это когда загружается каждый файл и обрабатывается по отдельности. (тот же объем за 2 сек).

Не могу понять в чем проблема.
Почему CopyFrom так медленно работает?

почему именно CopyFrom?
Вот второй вариант который работает 2 сек.
While 0 to 10 do
begin
  StreamTmp.Clear;                              
  StreamTmp.LoadFromFile(NameFiles);            
  Обработка данных
end;


begin...end   (2006-01-11 08:22:00) [1]

> Johnmen ©   (10.01.06 21:54) [17]

...что и подразумевалось ещё в [5].


beglec   (2006-01-10 23:04:00) [2]

Спасибо разобрался :))

P.S. CopyFrom, больше не использую.


Johnmen   (2006-01-10 21:54:00) [3]

Т.е. не для вр.буфера, а для результирующего стрима, на каждой итерации :)


Johnmen   (2006-01-10 21:52:00) [4]

>begin...end ©   (10.01.06 21:28) [15]

Да-да. Совершенно верно!
Реаллокация для вр.буфера делается намного чаще, в 5м/$F000 раз :)


begin...end   (2006-01-10 21:28:00) [5]

> Johnmen ©   (10.01.06 21:15) [14]

$F000 байт. Исходники читать -- оно рулёз.


Johnmen   (2006-01-10 21:15:00) [6]

>begin...end ©   (10.01.06 20:37) [13]
>Не 5.

А сколько?


begin...end   (2006-01-10 20:37:00) [7]

> Johnmen ©   (10.01.06 20:29) [12]

> 5м временного буфера на операцию CopyFrom

Не 5.


Johnmen   (2006-01-10 20:29:00) [8]

>beglec ©   (10.01.06 18:25) [10]
>может быть может быть. но по идеи не должно. :)

Не знаю о твоих идеях, а вот по моим очень даже должно.
Вот смотри. Пусть файлы по 5 метров (5м).
На каждой итерации аллокируется 5м под "рабочий" стрим, 5м временного буфера на операцию CopyFrom, и самое главное - (n+1)*5м под результирующий стрим. При этом гоняются байты - 5м в "рабочий" (чтение из файла), потом они во вр.буфер, потом (после аллокации) n*5м из результирующего в реаллокируемый, ("старый" рез-щий освобождается), потом 5м в этот реаллок-ый, ну и освобождение временного...
Т.е. помимо плотной работы с ММ (просили всё больший на 5м кусок + вр.куски) мы прогнали 5м+5м+n*5м+5м байтов!
Неплохо поработали! Тормозили, однако...:)


Reindeer Moss Eater   (2006-01-10 20:19:00) [9]

Во втором варианте виртуальной памяти съедается меньше.
Больше одного файла за раз не обрабатывается.


beglec   (2006-01-10 18:25:00) [10]

-> Reindeer Moss Eater ©
Какой файл подкачки :))?
второй пример видишь ???? который работает гораздо быстрее.
в память в "сасывается" при помощи

StreamTmp.LoadFromFile(NameFiles);            


->Johnmen ©  
может быть может быть. но по идеи не должно. :)


Johnmen   (2006-01-10 18:03:00) [11]

Видимо из-за этого
Using CopyFrom eliminates the need for the user to create, read into, write from, and free a buffer when copying data.
хоть и скрыто от юзера, но существует. Дергается постоянно ММ, да и размер выделяемый одним куском 5-6Mb, не сразу найдёт...:)


Reindeer Moss Eater   (2006-01-10 17:59:00) [12]

Тормозит файл подкачки.
Ты же все свои 101 файл всасываешь в TMemoryStream.


beglec   (2006-01-10 17:53:00) [13]

Цикл был для примера :))) 10-11 а также 101 файл значения не имеют.
вопрос был не про циклы а про скорость работы! :)))

> Algol   (10.01.06 14:54) [4]
100% никакого чтения из файла не происходит :)))
это легко посмотреть увеличив цикл на более выское число и посмотреть моргает ли лампочка HDD :))


Johnmen   (2006-01-10 17:31:00) [14]


> beglec ©   (09.01.06 10:28)  
> While 0 to 10 do


Можно уточнить, что это значит?
Если это for i:=0 to 10, то это 11 "файлов"


begin...end   (2006-01-10 17:06:00) [15]

> beglec ©   (09.01.06 10:28)

> Почему CopyFrom так медленно работает?

Я не уверен, но могу предположить, что замедление происходит из-за реаллокаций памяти в методе TMemoryStream.SetCapacity.

> Algol   (10.01.06 14:54) [4]

> На самом деле происходит не просто копирование одного потока
> в другой, но и чтение файла.

Что Вы имеете в виду?


Algol   (2006-01-10 14:54:00) [16]

Работает долго потому, что вот здесь
StreamFull.CopyFrom(StreamTmp,StreamTmp.Size);
На самом деле происходит не просто копирование одного потока в другой, но и чтение файла.


beglec   (2006-01-09 11:04:00) [17]

Особой разницы нет.
Вопрос в данный момент не в этом.

P.S. Хотя по логиге вещей TFileStream должен работать медленнее.
MemoryStream
загрузил данный одним махом.
обработал данные
сбросил данные на диск.

FileStream
загрузил кусок
обработал данные
сбросил кусок

Сколько раз будет дергаться HDD ?
Чтение запись на диск всегда проигрывали обработке данных в памяти. Или сейчас технологии изменились. На сколько помню нет. HDD до сих пор является одним из узких звеньев в компьютере, даже если там будет мега кэш.

P.S.S. 1 файл 5-6Mb – 1 запись=10 байт.


Плохиш   (2006-01-09 10:48:00) [18]

Почему бы не сделать StreamTmp: TFileStream;?


beglec   (2006-01-09 10:30:00) [19]

Переделал все на второй вариант, но хотелось бы все таки разобраться почему так?


Наверх

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