![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Самый быстрый способ считать маленький файл в строку
Nucer © (2011-10-13 15:59:00)Подскажите самый быстрый способ считать файл в RawByteString. Необходимо обрабатывать около 50 тысяч файлов размеров в 100-200 килобайт.
При таком варианте только на чтение без обработки уходит минут 5:
var
S: RawByteString;
F: File;
Size: Int64;
begin
AssignFile(F, Filename);
Reset(F, 1);
Size := FileSize(F);
Reset(F, Size);
SetLength(S, Size);
BlockRead(F, S[1], 1);
CloseFile(F);
end;
Игорь Шевченко (2011-10-14 21:29:00) [21]Rouse_ © (14.10.11 21:19) [41]
> Начиная с 2007-ой дельфи асм реализаця части функций очень
> сильно похорошела
в RTL от XE2 все те же REPNE SCASB
Rouse_ (2011-10-14 21:24:00) [22]
> Игорь Шевченко © (14.10.11 21:20) [42]
Согласен, CLMUL инструкции плана PCLMULLQLQDQ/PCLMULQDQ туда-же, но я не об этом, а о том что код не оптимизирован :)
Игорь Шевченко (2011-10-14 21:20:00) [23]Rouse_ © (14.10.11 20:57) [37]
1. наборы SSE и VMX тебя приятно поразят разнообразием применения префиксов группы REP.
2. В Intel сидят далеко не дураки, и в новых архитектурах они оптимизируют выполнение старого набора инструкций.
"Intel microarchitecture (Nehalem) improves the performance of REP strings significantly
over previous microarchitectures in several ways:
• Startup overhead have been reduced in most cases relative to previous microarchitecture,
• Data transfer throughput are improved over previous generation
• In order for REP string to operate in “fast string“ mode, previous microarchitectures
requires address alignment. In Intel microarchitecture (Nehalem), REP
string can operate in “fast string” mode even if address is not aligned to 16 bytes"
(Intel® 64 and IA-32
Architectures
Optimization Reference Manual
Order Number: 248966-020
November 2009)
http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html
там оно правда про MOVSx
Rouse_ (2011-10-14 21:19:00) [24]
> Игорь Шевченко © (14.10.11 20:56) [36]
> Во-вторых, открываем внутренности VCL и видим примеры нормального
> ассемблера.
Начиная с 2007-ой дельфи асм реализаця части функций очень сильно похорошела за счет использования наработок сторонних разрабочиков, часть пошла от Fast Code часть от Пиета, поэтому я и спросил по поводу "старых дельфийских библиотек"
Rouse_ (2011-10-14 21:11:00) [25]
> Anatoly Podgoretsky © (14.10.11 21:06) [38]
> Это пример не профессионализма. Тупо сделаный код.
Собственно именно эту мысль я и попытался озвучить в первом посте :)
Rouse_ (2011-10-14 21:09:00) [26]
> Игорь Шевченко © (14.10.11 20:56) [36]
> Во-первых, на цитату из мануала нефигово приводить ссылку.
Ну блин: http://developer.intel.com/design/pentiumii/manuals/245127.htm
Ну и до кучи: http://agner.org/optimize/
Anatoly Podgoretsky (2011-10-14 21:06:00) [27]
> ужс, кто "такому ассемблеру" учит?
Это пример не профессионализма. Тупо сделаный код. Не читая ни умных книг, не руководство по оптимизации от Интела, не вглядываясь в генофонд.
Rouse_ (2011-10-14 20:57:00) [28]ЗЫ: кусок из реализации дизасма, где описаны все 4 группы префиксов (если я не прав - поправь, скажу спасибо):
const
// Lock and repeat prefixes:
pfxLock = $F0;
// The LOCK prefix can be prepended only to the following instructions and only to those forms
// of the instructions where the destination operand is a memory operand: ADD, ADC, AND,
// BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR,
// XADD, and XCHG
pfxRepn = $F2;
pfxRep = $F3;
// Segment override prefixes:
pfxCSSegmentOverride = $2E;
pfxSSSegmentOverride = $36;
pfxDSSegmentOverride = $3E;
pfxESSegmentOverride = $26;
pfxFSSegmentOverride = $64;
pfxGSSegmentOverride = $65;
// Operand-size override prefix
// (when used with the escape opcode 0FH, this
// is treated as a mandatory prefix for some SIMD instructions)
pfxOperandSizeOverride = $66;
pfxEscapeOpcode = $0F;
// Address-size override prefix
pfxAddressSizeOverride = $67;
Игорь Шевченко (2011-10-14 20:56:00) [29]Во-первых, на цитату из мануала нефигово приводить ссылку.
Во-вторых, открываем внутренности VCL и видим примеры нормального ассемблера.
В-третьих, помним первый принцип оптимизации - по возможности ее избегать.
Rouse_ (2011-10-14 20:50:00) [30]
> Rouse_ © (14.10.11 20:28) [33]
> Нормальный ассемблер
Интеловские мануалы в плане профилирования кода с тобой не согласны, особливо в части рекомендаций по использованию исключающих префиксов опкодов первой группы (из четырех):
pfxRepn = $F2;
pfxRep = $F3;
куда идут инструкции типа REPNE/REPNZ и т.д. тратящие пять тиков минимум на итерации, так и инструкции LOOP например...
Впрочем ты и сам это должен помнить...
Игорь Шевченко (2011-10-14 20:41:00) [31]Rouse_ © (14.10.11 20:28) [33]
Нормальный ассемблер
Rouse_ (2011-10-14 20:28:00) [32]
> REPNE SCASB
ужс, кто "такому ассемблеру" учит? Это из старых дельфийских библиотек или самописка?
Игорь Шевченко (2011-10-14 20:11:00) [33]цель чтения файлов не озвучена.
Inovet (2011-10-14 12:01:00) [34]> [22] MBo © (14.10.11 08:53)
> Просто вход в папку с 20тыс мелких файлов FAR или проводником
> (в режиме без иконок) в первый раз занимает около минуты,
> во второй раз несколько секунд, но тоже не мгновенно.
Так он их имена и пр. грузит в свои структуры, а для открытия файла достаточно найти один в каталоге. На NTFS это быстро - каталог двоичное дерево, на FAT долго - каталог линейный.
Slym (2011-10-14 11:28:00) [35]первый запуск 29700:10215 т.е. 30 сек по всему диску d:\ по маске pas+dcu найдено 10215 файлов
второй запуск 9900:10215
чтение побайтовое :) REPNE SCASB
function LCharPos(Str:PChar;char:char;Size:integer): Integer;
asm {Str - EAX, char - DL (EDX), Size - ECX}
PUSH EDI
MOV EDI, EAX { Point EDI to str}
MOV AL,DL { AL = Search char}
MOV EDX,ECX {remember Length}
REPNE SCASB
JNE @@fail
MOV EAX,EDX { Calc offset }
SUB EAX,ECX
JMP @@fin
@@fail:
XOR EAX,EAX
@@fin:
POP EDI
end;
procedure FastOpenFile(const FileName:string);
var
i:integer;
hFile,hMap:THandle;
hMem:pointer;
begin
try
hFile:=CreateFile(PChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);
if hFile=INVALID_HANDLE_VALUE then RaiseLastOSError;
hMap:=CreateFileMapping(hFile,nil,PAGE_READONLY,0,0,nil);
if hMap=0 then RaiseLastOSError;
hMem:=MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
if hMem=nil then RaiseLastOSError;
LCharPos(hMem,#1,GetFileSize(hFile,nil));
UnmapViewOfFile(hMem);
CloseHandle(hMap);
CloseHandle(hFile);
except
end;
end;
procedure TForm1.EnumFolder(dir:string);
var
f:WIN32_FIND_DATA;
hf: HFile;
flag: boolean;
begin
dir:=IncludeTrailingPathDelimiter(dir);
hf:=FindFirstFile(PChar(dir+'*.*'),f);
while FindNextFile(hf,f) do
begin
if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)>0 then
begin
if (StrComp(f.cFileName,'.')<>0) and (StrComp(f.cFileName,'..')<>0) then
EnumFolder(dir+f.cFileName);
end else
begin
if (pos('.pas',f.cFileName)>0) or (pos('.dcu',f.cFileName)>0) then
begin
inc(fc);
FastOpenFile(dir+f.cFileName);
end;
end;
end;
windows.FindClose(hf);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
t:dword;
begin
fc:=0;
t:=GetTickCount;
EnumFolder('d:\');
t:=GetTickCount-t;
Caption:=InttoStr(t)+':'+InttoStr(fc);
end;
QAZ (2011-10-14 11:27:00) [36]
> han_malign (14.10.11 11:03) [28]
данунафиг я такими файлофункциями в жизни не пользовался и не собираюсь
han_malign (2011-10-14 11:03:00) [37]
> ктож блин, читает файлы по байту?
- кури мануал...
procedure Reset(var F: file; RecSize: Integer);
QAZ (2011-10-14 10:47:00) [38]
> Nucer (13.10.11 16:19) [5]
ктож блин, читает файлы по байту?
минимальная единица чтения должна быть равна размеру кластера
а при твоих размерах нужно читать весь файл зараз
han_malign (2011-10-14 10:05:00) [39]
> И я сталкивался с тем, что FindFirst/Next безо всяких гуёв по подобным папкам выполняется в первый раз ощутимое время
- проверка прав - скорее всего...
Можно попробовать поиграться с владельцем, наследованием и т.д., но правильнее всего разбивать такую лапшу на дерево подпапок(при грамотном именовании можно делать(загрубленно) и фильтрацию, и сортировку)...
З.Ы. Сам не проверял, но некоторые клиенты утверждают, что после 64К наступает полная опа...
MBo (2011-10-14 09:26:00) [40]>обавление 20тыс элементов в TListView
В Far примерно то же самое.
И я сталкивался с тем, что FindFirst/Next безо всяких гуёв по подобным папкам выполняется в первый раз ощутимое время