Прочитав умные мысли про то, что память эффективнее выделять кусками, размер которых равен степени 2, я решил применить её в D7, подменив менеджер памяти на свой, отличающийся только тем, что размер блока дополняет до степени 2, и сравнить эффективность родного менеджера и подкорректированного.
{$APPTYPE CONSOLE}
uses
Windows;
type
proc = procedure;
procedure Stress; // думаю, достаточно интересная задача для менеджера памяти
var
p1, p2, p3, p4: array of byte;
i: integer;
begin
for i := 0 to 999999 do begin
SetLength(p1, i);
SetLength(p2, i);
SetLength(p3, i);
SetLength(p4, i);
end;
end;
procedure Test(p: proc);
var
T: cardinal;
begin
T := GetTickCount; while T = GetTickCount do; T := GetTickCount;
p;
WriteLn(integer(GetTickCount) - integer(T));
end;
function MyReallocMem(p: Pointer; size: Integer): Pointer; // äîïîëíèòü äî ñòåïåíè 2
var
aSize: integer;
begin
if size = 0 then aSize := 0 else begin
aSize := 1;
while aSize < size do aSize := aSize shl 1;
end;
Result := SysReallocMem(p, size);
end;
var
M: TMemoryManager;
begin
Test(Stress);
M.GetMem := SysGetMem;
M.FreeMem := SysFreeMem;
M.ReAllocMem := MyReAllocMem;
SetMemoryManager(M);
Test(Stress);
ReadLn;
end.
> Это где такие мысли написаны? Можно нам тоже почитать?
Сходу не найду, но вот тут упоминается: http://russian.joelonsoftware.com/Articles/BacktoBasics.html
> Хитрые программисты борются с фрагментацией памяти, выделяя каждый раз память блоками, размер которых равен степени двойки. Ну вы знаете, 4 байта, 8 байт, 16 байт, 18446744073709551616 байт, и т.д. По причинам, которые должны быть очевидны для тех, кто играл с конструктором Lego, это уменьшает фрагментацию списка свободных блоков. Несмотря на то, что такой подход кажется расточительным, также легко показать, что при нём неиспользуемой остаётся не более чем 50% памяти. Так что ваша программа использует не более чем в два раза больше памяти, чем ей надо, что не так уж страшно.
Допустим, вы написали хитрую функцию strcat, которая изменяет по необходимости размер буфера для хранения результата. Сколько именно памяти ей имеет смысл выделять? Ровно столько, сколько сейчас надо? Мой учитель и наставник Стэн Эйзенстет (Stan Eisenstat) рекомендует при вызове realloc удваивать количество памяти по сравнением с прошлым разом. Это значит, что вам никогда не придётся вызывать realloc больше чем lg n раз, что неплохо с точки зрения производительности даже для огромных строк, и вы потратите впустую не больше 50% памяти.
Добавлено через 2 мин.
Я сюда опечятался. Я мерял для Result := SysReallocMem(p, aSize), иначе не меняется ничего.