Подскажите, как создать большой буфер для текста на 3-5 МБ?? или способы хранения текста такого объема.
Valentin Большой буфер - это 2-4 гб, а 3-5 мб легко задать с помощью функций для работы с памятью, рекомендую GetProcessHeap\HeapAlloc т.к. это самый простой и проверенный способ + буфер растет автоматически Global* советую не использовать и не только я, но и многие крупные компании...
Собственно тема на форуме уже много раз была - Gloal\Local Alloc оставлены для совместимости с win16 (а уже эпоха win64 пришла Они не только тормозят, но и сама заложенная в них концепция перемещаемой памяти умерла вместе с win16. В win32 GloalAlloc следует использовать только для clipboard, который в эпоху перехода с 16 на 32 был сделан криво - работает по механизму win16 (чтобы работало копирование в/из старые программы), вместо того чтобы новый clipboard интерфейс сделать 32, а для 16 битных прог предусмотреть специальный механизм обращения к нему вроде эмуляции. Не стоит и дальше плодить подобные нелепости закладывая их в новые программы, способные без этого обойтись - современный и достаточно шустрый аналог - HeapAllоc. Хотя если 3-5Мб буфер "статичный" - один раз выделил и долго работаешь то лучше VirtualAlloc, поскольку в этом случае HeapAllоc всё равно в неё переадресуется, а если буфер совсем мелкий <512кБ или часто освобождается - перевыделяется то HeapAllоc позволяет существенно сэконосмить время из-за более быстрого менеджмента и отсутствия обнуления памяти. http://www.wasm.ru/forum/viewtopic.php?id=30074 http://www.wasm.ru/forum/viewtopic.php?id=30291
Да, и для больших буферов как у ТС лучше использовать VirtualAlloc. Куча - для относительно небольших блоков. ----- Опередили
Примерные соотношения времени выделения+освобождения блока памяти для HeapAlloc и GlobalAloc см.например тут. Вывод: с притормаживанием GMEM_FIXED еще можно смириться (например, ради лени юзанья GetProcessHeap), а вот GMEM_MOVEABLE - полный отстой, бессмысленный и тормозной
leo Я бы сделал обратный вывод - GMEM_MOVEABLE приходится юзать для clipboard (за неимением альтернативы), а в остальных случаях применение морально устаревших концепций - плохой стиль, даже если проигрыш в тактах не столь существенен.
Буфер не статический. Я разбираю относительно большой текст и формирую длинную строку. ------------------------кусочек--------------- invoke lstrcat,addr buffer100,addr buf6 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf7 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf8 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf9 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf10 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf11 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf12 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf19 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf13 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf14 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr buf15 invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr ModUb invoke lstrcat,addr buffer100,addr Tab invoke lstrcat,addr buffer100,addr bufexp1C invoke lstrcat,addr buffer100,addr Ks --------------------------------------------- Она может быть и 3МБ и 10МБ ( но не более) и лежать в buffer100.
Лучше выделить 10Мб через VirtualAlloc - главное не освобождать/перевыделять её при разборе следующей строки, а юзать для всех строк один и тот же буфер. 10Мб не тот размер чтобы заморачиваться с растущим буфером.
Y_Mur А как со скоростью, если перевыделять память после каждой строки?? Ведь разбираемых строк у меня десятки тысяч, соединенные в одну. Или я что-то не так понял??
Valentin Я правильно понял? есть: 1. файл отображённый/прочитанный в память 2. буфер 3-10Мб под строку 3. из файла мелкими кусками дёргаются подстроки и заносятся в буфер-строку 4. обработанная строка куда используется или сохраняется и больше не нужна 5. буфер 3-10Мб под строку можно считать свободным и использовать для "надёргивания" новой строки В этом случае затраты времени на освобождение/повторное выделение памяти (см. ссылку в #8) полюбому лишние, ведь новая строка просто будет затирать старую и обнуление не нужно.
Valentin УжОс, и ты еще про скорость спрашиваешь Для чего юзать десятк-сотни раз lstrcat, которая при каждом вызове определяет результирующую длину строки в мегабуфере buf100 ?! Нужно хранить указатель bufend на конец строки buf100, копировать строчки по этому указателю и соотв-но передвигать bufend на добавленную длину
Y_Mur Плохой стиль это когда юзаешь "то - не знаю что", а если знаешь, что в итоге GlobalAlloc(0,...) == GetProcessHeap+HeapAlloc, то почему бы и не использовать ради мелочной экономии одной строчки кода А вот юзать GMEM_MOVEABLE "просто так" (т.е.не для clipboard и DDE) просто бессмысленно, т.к. и кода больше приходится писать и тормозов существенно больше и занимаемой памяти (под таблицу хэндлов), а смысла никакого, т.к. в нормальной ситуации в куче все равно ничто никуда не перемещается, разве что при принудительном вызове HeapCompact, и то не факт
leo Спасибо за совет, опыта маловато, а задачи приходится решать нелегкие. "Я -не волшебник, я только учусь".