Последние записи
- Писать/читать файл блоками или целиком (BlockWrite, BlockRead)?
- Посимвольное чтение из файла. Посимвольная запись в файл
- Разделить строку с сохранением разделителя
- Свой прогресс в консоли при выполнении команды ffmpeg
- HttpWebRequest выдаёт много ошибок при неудачном соединении
- Как обратиться к последней ячейке не связанного диапазона
- Управление громкостю MediaPlayer
- Как использовать java для бэкенда веб-сайтов и веб-скриптов?
- Некорректная работа гиперссылок Microsoft Word 2010
- Функция рисования для печати на принтере ScanLine
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
20th
Авг
Писать/читать файл блоками или целиком (BlockWrite, BlockRead)?
Posted by obzor under Delphi, Pascal
Блоками по 1 байт не очень хорошо.
Или это будет кэшироваться?
Оптимально блок должен быть размера блока операционной системы на диске.
Это не имеет отношения к размерам кластера на диске.
Блоки данных пишутся в кластеры.
Если размер блока данных меньше или больше размера кластера, то часть дискового пространства тратится впустую.
Если размер блока данных кратный размеру кластера — то тоже всё хорошо.
Я со смыслом пишу — смысл прямой, если вы не заметили.
И стараюсь мыслить логически.
Я только хотел рассказать о связи записи/чтения блоками с размером кластера на диске.
Кластер — это по сути блок данных диска.
Если вы понимаете, как работает файловая система, то и размер блока данных для записи/чтения выберете оптимально.
Вот что мне нейронка выдала (код рабочий, но пришлось с ней немного подискутировать, чтобы она из говнокода изначально родила что-то более-менее похожее на требуемое):
program DiskDiagnostics;
{$mode objfpc}{$H+}
uses
SysUtils;
const
BLOCK_SIZE = 4096;
BUF_MB = 500;
type
TByteArray = array of Byte;
function CreateBuffer(SizeInBytes: Integer): TByteArray;
var
i: Integer;
begin
SetLength(Result, SizeInBytes);
for i := 0 to High(Result) do
Result := Random(256);
end;
procedure WriteWholeFile(const AFileName: string; const Buffer: TByteArray);
var
f: File;
BytesWritten: LongInt;
begin
AssignFile(f, AFileName);
Rewrite(f, 1);
BlockWrite(f, Buffer[0], Length(Buffer), BytesWritten);
CloseFile(f);
end;
procedure WriteBlockFile(const AFileName: string; const Buffer: TByteArray);
var
f: File;
Offset, BytesToWrite, BytesWritten: Integer;
begin
AssignFile(f, AFileName);
Rewrite(f, 1);
Offset := 0;
while Offset < Length(Buffer) do
begin
BytesToWrite := BLOCK_SIZE;
if Offset + BytesToWrite > Length(Buffer) then
BytesToWrite := Length(Buffer) - Offset;
BlockWrite(f, Buffer[Offset], BytesToWrite, BytesWritten);
Inc(Offset, BytesToWrite);
end;
CloseFile(f);
end;
function ReadWholeFile(const AFileName: string): TByteArray;
var
f: File;
FileSizeBytes: Int64;
BytesRead: LongInt;
begin
AssignFile(f, AFileName);
Reset(f, 1);
FileSizeBytes := FileSize(f);
SetLength(Result, FileSizeBytes);
BlockRead(f, Result[0], FileSizeBytes, BytesRead);
CloseFile(f);
end;
function ReadBlockFile(const AFileName: string): TByteArray;
var
f: File;
FileSizeBytes: Int64;
Offset, BytesToRead, BytesRead: Integer;
begin
AssignFile(f, AFileName);
Reset(f, 1);
FileSizeBytes := FileSize(f);
SetLength(Result, FileSizeBytes);
Offset := 0;
while Offset < FileSizeBytes do
begin
BytesToRead := BLOCK_SIZE;
if Offset + BytesToRead > FileSizeBytes then
BytesToRead := FileSizeBytes - Offset;
BlockRead(f, Result[Offset], BytesToRead, BytesRead);
Inc(Offset, BytesToRead);
end;
CloseFile(f);
end;
var
WriteBuffer: TByteArray;
ReadBuffer: TByteArray;
StartTime, EndTime: QWord;
begin
Randomize;
WriteBuffer := CreateBuffer(BUF_MB * 1024 * 1024);
Writeln('Buffer created, size: ', Length(WriteBuffer), ' bytes (', BUF_MB, ' MB)');
Writeln('Block size: ', BLOCK_SIZE, ' bytes');
Writeln;
StartTime := GetTickCount64;
WriteWholeFile('test1.dat', WriteBuffer);
EndTime := GetTickCount64;
Writeln('Write whole: ', EndTime - StartTime, ' ms');
StartTime := GetTickCount64;
WriteBlockFile('test2.dat', WriteBuffer);
EndTime := GetTickCount64;
Writeln('Write blocks (', BLOCK_SIZE, '): ', EndTime - StartTime, ' ms');
StartTime := GetTickCount64;
ReadBuffer := ReadWholeFile('test1.dat');
EndTime := GetTickCount64;
Writeln('Read whole: ', EndTime - StartTime, ' ms');
StartTime := GetTickCount64;
ReadBuffer := ReadBlockFile('test2.dat');
EndTime := GetTickCount64;
Writeln('Read blocks (', BLOCK_SIZE, '): ', EndTime - StartTime, ' ms');
Writeln;
Writeln('Diagnostics finished. Press Enter...');
Readln;
end.
И так, есть материал для тестов. Задача проверить, что быстрее читать и писать файл целиком или кусочками по 4096 байт.
А результаты оказались совершенно аномальными и не дающими однозначного ответа.
Запуск на HDD:
Write whole: 3218 ms
Write blocks (4096): 579 ms
Read whole: 125 ms
Read blocks (4096): 421 ms
На другом HDD:
Write whole: 4797 ms
Write blocks (4096): 656 ms
Read whole: 140 ms
Read blocks (4096): 407 ms
На SSD (M.2):
Write whole: 250 ms
Write blocks (4096): 1000 ms
Read whole: 140 ms
Read blocks (4096): 453 ms
Выводы
На HDD быстрее в 5-7 раз писать блоками по 4096, а не целиком файл, но быстрее в 3 раза читать файл целиком, а не блоками.
На SSD быстрее в 4 раза писать файл целиком, а не блоками, быстрее в 3 раза читать файл целиком, а не блоками.
То есть читать файл всегда в приоритете целиком, а не блоками. Плюс меньше и чище код.
С записью нет однозначного ответа. Если нужна жесткая оптимизация, то тебе придется делать две версии кода: для записи целиком и блоками. А далее определять тип диска, если это HDD, то вызывать метод записи блоками, если SSD — метод записи целиком. Но так как требуется реально заморачиваться, то в самом простом случае можно просто писать файл целиком, а не блоками, так как код меньше и чище.
Да, надо еще учесть, что у HDD тоже есть буфер, и он явно влияет на результат. Твоя программа не знает, каков буфер, и как он работает. Например, как так получилось, что на HDD запись блоками раза в 2 выше, чем на скоростном M.2? Очевидно, что это не физическая запись на диск, а запись в буфер. Однако после переполнения буфера в теории скорость должна резко упасть.
Что еще удивительно. На все трех дисках чтение показало примерно одинаковую скорость, не важно, блоками или целиком и с HDD или SSD.
Итоговый вывод
Пишите и читайте файл целиком, а не заморачивайтесь. Код проще и чище. А угадать какой там тип диска, какой у него буфер, на сколько он фрагментирован и прочее это уже за гранью простой задачи записи и чтения файла…
P.S. Блоки по 65536 байт дали чуть другой результат:
HDD №1:
Write whole: 2703 ms
Write blocks (65536): 157 ms
Read whole: 125 ms
Read blocks (65536): 250 ms
HDD №2:
Write whole: 4078 ms
Write blocks (65536): 109 ms
Read whole: 125 ms
Read blocks (65536): 141 ms
SSD:
Write whole: 234 ms
Write blocks (65536): 141 ms
Read whole: 109 ms
Read blocks (65536): 156 ms
Вот тут уже более предсказуемый результат: во всех случаях писать быстрее блоками по 65536, читать быстрее целиком.
P.P.S.
Вот результат, когда подсунул ему читать незнакомый файл, а не тот, что только что сам записал (это HDD):
Read whole: 2875 ms
Read blocks (65536): 2968 ms
То есть дело в кэше диска, который существенно влияет на результат. Короче, результаты заранее вообще непредсказуемы, и потому всегда проще читать и писать файл целиком, а не блоками, чтобы не заморачиваться. Таков будет окончательный вывод!
Похожие статьи
Купить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту

пеллетные котлы

Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)


