Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты, TMemoryStream,TFileStream скорость работы? почему такая разная скорость работы? 
:(
    Опции темы
WDeveloper
Дата 6.2.2007, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 31.1.2007

Репутация: нет
Всего: нет



Посылаю файл размером 4 мб ( изображение ) с сервера на клиент посредством TServerSocket, TClientSocket.
На сервере я открываю через TFileStream изображение, потом формирую TMemoryStream с лидирующим числом ( кол-во байт в пакете ). Т.к. сокеты это поток - тут нужно следить за тем сколько пакетов вышло и когда пришёл последний.
Вот.. далее:
Код
ServerSocket1.Socket.Connections[0].SendStream( MS );

и изображение уходит клиенту. Где оно уже собирается воедино и отображается так:
Код
Image1.Picture.Bitmap.LoadFromStream( SOMEStream );


Но вот в чём вопрос. Если на клиенте формировать входящий поток ( изображения ) в TMemoryStream то процесс длиться ~ 5 секунд, в то время как при использовании TFileStream:
Код
FS := TFileStream.Create( 'file.bmp', fmCreate or fmShareDenyWrite );

процесс длиться ~0.8 секунды.

Почему такая огромная разница во времени?? 
Винт не слишком быстрый, 7200 рпм, 2 мб кэш. Оперативки 512. Проц 2.8 Ггц.
PM MAIL   Вверх
Snowy
Дата 6.2.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Ну во-первых кэширование винта.
Во-вторых, приём стрима - не самый оптимальный вариант.
Рекомендую следующий порядок действий:
Получить размер.
Выделить под него необходимый кусок памяти.
Читать из сокета буфер, а не стрим, в эту память.
В случае со стримом происходит постоянное перевыделение памяти, что замедляет процесс.
Особенно это видно при недостатке памяти, малой скорости памяти, загруженности системы или не очень мощном процессоре.

Добавлено @ 11:24 
Да. Забыл.
Можно модифицировать более простым путём.
MemoryStream.SetSize(размер_данных);
Это исключит перевыделение памяти.
PM MAIL   Вверх
WDeveloper
Дата 6.2.2007, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 31.1.2007

Репутация: нет
Всего: нет



Ну в принципе прием на клиенте у меня походу так и сделан:
Код

  FS: FileStream; // создан ранее

var
  Bfr: Pointer;
  StreamLength : Cardinal;

begin

  StreamLength := Socket.ReceiveLength;
  GetMem( Bfr, StreamLength );
  
  try

    Socket.ReceiveBuf( Bfr^, StreamLength );

    // здесь определяется первый ли этот пакет или нет, если нет добавляю в конец потока:
    FS.Seek( 0, soFromEnd );
    FS.Write( Bfr^, StreamLength );

    // если это первый пакет чуть ранее этих двух строк я нахожу в потоке символ "|" - он у меня отделяет контрольную длину от старта пакета. 
// И сосбственно отделённый пакет от контрольной записываю в начало файлового потока:
        for I1 := I+1 to StreamLength-1 do
          FS.Write( Char ( ( PChar( Bfr ) + I1 )^ ), 1 );

// и когда уже пакет последний, то просто отображаю его на Имидж:
FS.Position := 0;
Image1.Picture.Bitmap.LoadFromStream( FS );
...

Про перевыделение памяти не понял. Это на клиенте, при приеме? Куда этот SetSize-то прикрутить нужно?

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0419 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.