![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
не устраивает ReallocMem
Ruzzz © (2007-12-10 23:40:00)в хелпе написано:
if P is not nil and Size is not zero, ReallocMem reallocates the block referenced by P to the size given by Size. Existing data in the block is not affected by the reallocation, but if the block is made larger, the contents of the newly allocated portion of the block are undefined. If the block cannot be reallocated in place, it is moved to a new location in the heap, and P is updated accordingly.
Меня не устраивает этот MOVE! :)
Подскажите позжлста, есть ли какие-либо способы "бегать" Pointer'ом по "куску" памяти, который при этом сосотоит из частей? Т.е. я хочу вместо перераспределения памяти в случае не хватки, выделить еще и как-то это учитывать.
Может есть что-то подобное, например токой себе менеджер памяти :), обращаясь к памяти смотреть а не награнице ли мы части, если да то перепрыгиваем. Или это все "плохо"?
Мне нужен простой список строк, делитель #0, строки только добавляются, список не будет редактироваться, нужно очень быстро его составить, при этом в последствии нужно будет быстро по нему пробежаться (например также как и в SysUtils.StrEnd) и все, но изначально его длина не известна, она может быть как малой так и очень большой и поэтому заранее выделять много вроде как нельзя но и частое перераспределение(move) хочется обойти, но как же потом проходить по строкам если это будет не сплошной участок памяти?
Заранее спасибо!
DiamondShark (2007-12-11 14:07:00) [1]
> но я хочу оптимально оптимизировать программу
При твоих условиях (ожидаемые размеры списков) самый подходящий критерий оптимизации -- это понятность и простота алгоритмов и кода.
На накладные расходы можешь смело забить.
Ruzzz (2007-12-11 14:02:00) [2]на счет MemoryMappedFile, нада узнать как винда с ним работает, почитаю, думаю если последовательно его заполнять то проблем(скорость) с выделением новой памяти не должно быть.
Дерево это уже лишнее, его возможности просто не будут использоваться, а то что родительские папки в путях файлов не будут повторятся - это возможно важно. Операций копирования будет меньше, но будут другие :)
Ruzzz (2007-12-11 13:54:00) [3]MemoryMappedFile - тоже идея, и про дерево идея хорошая, действительно! подумаю над этим, спасибо!
@!!ex (2007-12-11 13:32:00) [4]> [38] Skyle © (11.12.07 13:30)
х.з.
Кстати, автор, а может тебе дерево хранить? Тогда не будет дублирующей информации.
И поиск файла, если что, будет значительно быстрее.
Skyle (2007-12-11 13:30:00) [5]
> @!!ex © (11.12.07 13:07) [35]
> > [34] Skyle © (11.12.07 13:05)
>
> Он не хранит файлы в памяти. Он хранит пути к ним, если
> я правильно понял.
Я тоже так понял. Просто вопрос такой: зачем одновременно в памяти 2 мильёна путей?
@!!ex (2007-12-11 13:21:00) [6]> [36] Ruzzz © (11.12.07 13:09)
ФАйл спроецированный в память.
MemoryMappedFile
Ruzzz (2007-12-11 13:09:00) [7]чесна говоря я не знаю что такое MMF, но в любом случае в оперативке быстрее будет
@!!ex (2007-12-11 13:07:00) [8]> [34] Skyle © (11.12.07 13:05)
Он не хранит файлы в памяти. Он хранит пути к ним, если я правильно понял.
Skyle (2007-12-11 13:05:00) [9]Может не стоит всё хранить в памяти? Хранить всё на диске и использовать MMF?
Ruzzz (2007-12-11 13:05:00) [10]%) шучу! :) всем спасибо за комментарии!
Ruzzz (2007-12-11 13:04:00) [11]да вы правы, оперция копирования строки и дисковые операции все сводят на нет.
думаю быстрее будет если написать драйвер и считывать по секторам MFT
sniknik (2007-12-11 12:57:00) [12]основные задержки в прикладном программировании не в улучшении стандартных механизмов, а в оптимальных алгоритмах.
> что программа стала работать быстрее... на 1%.
скорее даже наоборот на 10% медленнее...
Юрий Зотов (2007-12-11 12:50:00) [13]> Ruzzz © (11.12.07 12:26) [23]
Увы, сдается мне, что горьким будет Ваше разочарование...
После того, как Вы потратите кучу времени и труда, все сделаете - а в результате обнаружите, что программа стала работать быстрее... на 1%.
ЮЮ (2007-12-11 12:45:00) [14]> [21] @!!ex © (11.12.07 12:09)
> > [20] Ruzzz © (11.12.07 11:58)
> выполняется 110 мс...
> выделение 100!!! мегабайт по 100! БАЙТ.
> Вот как думаю: при 100.000 файлах - делаем и 100.000 раз
> new(обращений к менеджеру)! а так можна
Ну пусть даже сократишь с 0.2 секунды до абсоолютного 0, дальше то придется Винду переписывать, ибо
> да, заставить бы саму винду выдавать не по одному файлу!
> :) да еще и в заранее выделенную(подготовлинную:) память
Ruzzz (2007-12-11 12:38:00) [15]точнее бита, значить смогу быстренько в одном регистре смотреть, щас почитаю ваши комменты, спасибо большое, про дефрагментацию буду искать что-то
Ruzzz (2007-12-11 12:36:00) [16]SizeOf(TStrP) = 32 байта )
Сергей М. (2007-12-11 12:30:00) [17]
> устанавливаешь его Capacity равным ListCount * SizeOf(PChar)
Вру.
Просто Capacity <-- ListCount
@!!ex (2007-12-11 12:29:00) [18]> [23] Ruzzz © (11.12.07 12:26)
ИМХО это не правильно.
Копирование строки занимает больше времени, чем выделение памяти.
Ты сейчас не тем занимаешься.
Если уж так хочеться оптимизировать работу менеджера памяти - перед добавлением строк дефрагментируй память.
ТОгда realloc не будет ничего никуда перемещать, а просто расширять.
Сергей М. (2007-12-11 12:28:00) [19]
> "закидывать" элементы односвязного списка в заранее выделенный
> большой блок памяти
Это еще зачем ?
Строишь односвязный список, попутно подсчитывая число его элементов (ListCount).
По окончанию построения создаешь TList, устанавливаешь его Capacity равным ListCount * SizeOf(PChar), пробегаешь по построенному односвязному списку с попутным заполнением соотв. элеменов TList ссылками на строки, ассоциированные с соотв. элементами односвязного цикла.
Все !
И никаких множественных реаллокаций)
Ruzzz (2007-12-11 12:26:00) [20]Требования:
-сформировать как можна быстрее список строк
-список формируется последовательно(без вставок)
-в дальнейшем список изменятся не будет
-требуется быстро пройтись по списку
-требуется быстро сохранить в файл
-список может быть как очень мал так и очень огромен (при большом обьеме файлов и сложной иерархии подпапок == 2 000 000 строк * 100 (ну например средняя длина) = 200мб). Думаю при такой ситуации частое перераспределение(копирование уже имеющейся информации в новую область) может сильно тормозить.
Пока не изучал работу менежера, но вот что думаю:
хранить список указателей на строки, причем это будет простой масив а не односвязный список, а точнее хранить и длину:
TStrP = packed record
Offset: Pointer;
Size: Cardinal;
end;
эта область будет использовать ReAllocMem - думаю это не критично. будет что-то типа TStringList.Grow, но другой Delta, ведь я заранее знаю что строк будет много, по этой же причине и изначально буду выделять достаточно памяти. SizeOf(TStrP) = 8 байт - 100 000 строк - это 800 кб, нормально.
Теперь при "обходе" я не буду переживать за выход из какого-то выделленого кусочка памяти. проблема будет лишь при добавлении строки.
Но зная инфомацию о текущем выделеном куске памяти мы можем быстро выполнять проверку, и если что попросить еще памяти и переключится на нее.
При обходе пользоватся списком из TStrP. При сохранении сохранять блоки памяти.
осталось организовать как хранить инфу об этих блоках. Что-то типа менежер, но не менежер :) потому как не управляет, а просто хранит инфу. думаю тоже массив, который будет если что reallocmem использовать, но до этого в реальной ситуации не дойдет. елемент массива может быть такой:
TMemBlock = packed record
Offset: Pointer;
Size: Cardinal;
CurrentOffset: Pointer;
end;
CurrentOffset будет указывать на место для седующей строки. В этом случае можно будет его использовать как маркер конца в блоке при сохранении в файл. передвигать его будет просто при заполнении строками. а также использовать его при проверке хватит ли места под новую строку