Главная страница
    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.013 c
1-1131827370
Manufel
2005-11-12 23:29
2005.12.18
Запись элементов очень большого масива в файл с макс скоростью


4-1129470232
Svin
2005-10-16 17:43
2005.12.18
ReadFile


2-1133326401
BanderLog
2005-11-30 07:53
2005.12.18
Проблемы с VK_BACK


14-1132636419
TUser
2005-11-22 08:13
2005.12.18
Подключить USB хард к двум компьютерам


2-1133377141
kraim
2005-11-30 21:59
2005.12.18
ID жесткого





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