Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.02.12;
Скачать: [xml.tar.bz2];

Вниз

Долгое копирование потока. Как решить?   Найти похожие ветки 

 
beglec ©   (2006-01-09 10:28) [0]

Есть ли функция (альтернатива) значительно увеличивающая работу 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;


 
beglec ©   (2006-01-09 10:30) [1]

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


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

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


 
beglec ©   (2006-01-09 11:04) [3]

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

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

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

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

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


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

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


 
begin...end ©   (2006-01-10 17:06) [5]

> beglec ©   (09.01.06 10:28)

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

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

> Algol   (10.01.06 14:54) [4]

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

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


 
Johnmen ©   (2006-01-10 17:31) [6]


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


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


 
beglec ©   (2006-01-10 17:53) [7]

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

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


 
Reindeer Moss Eater ©   (2006-01-10 17:59) [8]

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


 
Johnmen ©   (2006-01-10 18:03) [9]

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


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

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

StreamTmp.LoadFromFile(NameFiles);            


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


 
Reindeer Moss Eater ©   (2006-01-10 20:19) [11]

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


 
Johnmen ©   (2006-01-10 20:29) [12]

>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м байтов!
Неплохо поработали! Тормозили, однако...:)


 
begin...end ©   (2006-01-10 20:37) [13]

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

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

Не 5.


 
Johnmen ©   (2006-01-10 21:15) [14]

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

А сколько?


 
begin...end ©   (2006-01-10 21:28) [15]

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

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


 
Johnmen ©   (2006-01-10 21:52) [16]

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

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


 
Johnmen ©   (2006-01-10 21:54) [17]

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


 
beglec ©   (2006-01-10 23:04) [18]

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

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


 
begin...end ©   (2006-01-11 08:22) [19]

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

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



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.02.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.047 c
1-1137403808
elfebet
2006-01-16 12:30
2006.02.12
Отчет в MS Word


15-1137629133
Bogdan1024
2006-01-19 03:05
2006.02.12
pay4click и его изотопы


2-1137611006
Sysanin
2006-01-18 22:03
2006.02.12
webBrowser


15-1137928997
Kerk
2006-01-22 14:23
2006.02.12
Google Books


3-1134459185
ANB
2005-12-13 10:33
2006.02.12
Посоветуйте тип блокировки записи (оракл)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский