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

Вниз

Запись элементов очень большого масива в файл с макс скоростью   Найти похожие ветки 

 
Manufel ©   (2005-11-12 23:29) [0]

Задача такая, есть динамичный массив типа byte, содержащий большое(около 10^7) количество элементов, необходимо записать его в файл
Я реализовал это так:

type
 ByteArr=array of byte;
 ByteFile=file of byte;
.....
procedure WriteBytesToFile(var B:ByteArr;var F:ByteFile);
var i:int64;
begin
 assignfile(f,MainForm.savefile.Text);
 rewrite(f);
 i:=0;
 while i<length(B) do
 begin
   write(f,B[i]);
   inc(i);
 end;
 Closefile(f);
end;

Реализация самая простая какая приходит в голову, она работает но массив записывается около минуты, хотя 10^7 байт это около 10 Мб, а на моей машине файлы такого размера копируются за 1-2 сек

Отсюда вопрос, как можно реализовать более эфективно запись всего этого массива в файл? Возможно существует какаянибудь функция в которою передаётся указатель на начало массива и его размер, записывающая всё напрямую из указаного промежутка адресов в оперативной памяти на жёсткий диск? Или же какаянибудь другая эффективная реализация?
Очень прошу помочь!

P.S. Извиняюсь за возможно несколько некоректную формулировку, я 2 года не занимался програмированием, и к сожалению растерял большую часть знаний :(


 
Eraser ©   (2005-11-12 23:32) [1]


> Manufel ©   (12.11.05 23:29)

Используй TFileStream и пиши напрямую память в которой расположен массив. Несколько секунд займёт.


 
Manufel ©   (2005-11-13 03:02) [2]

Разобрался с TFileStream, теперь время 0,25-0,41 сек :)
Спасибо большое!


 
злобная танька   (2005-11-13 09:06) [3]

а что круче TFileStream или BlockWrite?


 
begin...end ©   (2005-11-13 09:11) [4]

> злобная танька   (13.11.05 09:06) [3]

Если имеется в виду критерий скорости, то примерно одинаково (при правильном использовании). И в первом, и во втором случае запись в файл сводится к вызову WriteFile (API).


 
TUser ©   (2005-11-13 10:17) [5]

Писать по 1 байту - это заведомо медленно.

program wf;
{$apptype console}
uses Classes, SysUtils, DateUtils;

type
TProcedure = procedure;

const Count = 10000000;
     FastCount = 512;

var Ar: array [0..Count-1] of byte;

procedure Test (P: TProcedure);
var t: TDateTime;
begin
  t:=now;
  P;
  writeln ("Tested: "+inttostr(MillisecondsBetween(t,now)));
end;

procedure Write2File;
var i: integer;
    f: file of byte;
begin
 assignfile(f,"test");
 rewrite(f);
 for i:=0 to Count-1 do
   write (f,Ar[i]);
 Closefile(f);
end;

procedure WriteFast;
var i, j: integer;
    f: file;
    b: array [0..FastCount-1] of byte;
begin
 assignfile(f,"test");
 rewrite(f,1);
 j:=0;
 for i:=0 to Count-1 do begin
   b[j]:=Ar[i];
   inc (j);
   if j = FastCount then begin
     BlockWrite (f,b[0],FastCount);
     j:=0;
     end;
   end;
 BlockWrite (f,b[0],j);
 Closefile(f);
end;

procedure Write2Stream;
var f: TStream;
begin
 f:=TFileStream.Create("test",fmOpenWrite);
 f.WriteBuffer(Ar[0],Count);
 f.Free;
end;

begin
 Test (Write2File);
 Test (WriteFast);
 Test (Write2Stream);
end.


H:\temp\wf>dcc32 wf.dpr
Borland Delphi Version 15.0
Copyright (c) 1983,2002 Borland Software Corporation
wf.dpr(64)
65 lines, 0.11 seconds, 72228 bytes code, 10003621 bytes data.

H:\temp\wf>wf
Tested: 34672
Tested: 391
Tested: 297

H:\temp\wf>fpc -Mdelphi -OG2p3 wf.dpr
Free Pascal Compiler version 2.0.0 [2005/05/08] for i386
Copyright (c) 1993-2005 by Florian Klaempfl
Target OS: Win32 for i386
Compiling wf.dpr
Linking wf.exe
63 Lines compiled, 1.1 sec

H:\temp\wf>wf
Tested: 35890
Tested: 454
Tested: 311


 
Leonid Troyanovsky ©   (2005-11-14 08:37) [6]


> Manufel ©   (12.11.05 23:29)
 
> Отсюда вопрос, как можно реализовать более эфективно запись
> всего этого массива в файл? Возможно существует какаянибудь
> функция в которою передаётся указатель на начало массива
> и его размер, записывающая всё напрямую из указаного промежутка
> адресов в оперативной памяти на жёсткий диск? Или же какаянибудь
> другая эффективная реализация?


RTFM: CreateFileMapping, MapViewOfFile & etc

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2005-11-14 08:55) [7]

Leonid Troyanovsky ©   (14.11.05 08:37) [6]
Будет ли быстрее именно для данного случая?


 
Anatoly Podgoretsky ©   (2005-11-14 08:57) [8]

Да и о какой скорости тут говорить, когда 10 мб копируется за доли секунды, нет предмета для борьбы.


 
Leonid Troyanovsky ©   (2005-11-14 09:18) [9]


> Anatoly Podgoretsky ©   (14.11.05 08:55) [7]
> Leonid Troyanovsky ©   (14.11.05 08:37) [6]
> Будет ли быстрее именно для данного случая?


Если только записывать, то, конечно, не будет.
А если нужно не только писать, но и читать, то будет эффективней.

--
Regards, LVT.


 
PAVIA ©   (2005-11-14 20:40) [10]

Запустил код TUsera
Borland Delphi Version 14.0
FastCount=512
Tested: 38562
Tested: 140
Tested: 812

увеличел FastCount=4096 размер одной страницы памяти. Дальнейшие увеличение не имеет смысла, что и подтвердили эксперементы.
Tested: 38577
Tested: 63
Tested: 671


 
Manufel ©   (2005-11-17 18:47) [11]

Спасибо конечно, но я же написал что уже со всем разобрался, с использованием TFileStream скорость чтения из файла+обработки+записи в файл, 60-80 Мб, это занимает 1,5-2 секунды, и такая скорость меня вполне устраивает, а 10Мб те и обсуждать не стоит =)


 
Verg ©   (2005-11-17 18:55) [12]

type
ByteArr=array of byte;
.....
procedure WriteBytesToFile(var B:ByteArr);
var f : file;
begin
assignfile(f,MainForm.savefile.Text);
rewrite(f, 1);
  BlockWrite(f, B[0], length(B) );
Closefile(f);
end;


Бывает быстрее?


 
Leonid Troyanovsky ©   (2005-11-17 19:07) [13]


> Verg ©   (17.11.05 18:55) [12]

> Бывает быстрее?


Конечно.
Скинь дельфийские одежды - и быстрее на пару .. тактов.

--
Regards, LVT.



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

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

Наверх




Память: 0.49 MB
Время: 0.012 c
8-1112926472
Deedlit
2005-04-08 06:14
2005.12.18
ImageList => SpeedButton


14-1132829263
Ермак
2005-11-24 13:47
2005.12.18
Паскаль и С++ - различные понимания свободы?


2-1133393751
Юрий Ж.
2005-12-01 02:35
2005.12.18
[?]TClientSocket &amp; TServerSocket


4-1128742619
Sergey7
2005-10-08 07:36
2005.12.18
Обработка сообщений, когда программа в трэе


14-1132545057
atruhin
2005-11-21 06:50
2005.12.18
Организация ситемы электронного документооборота





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский