односвязный список

Тема в разделе "WASM.WIN32", создана пользователем Sickle, 26 мар 2006.

  1. Sickle

    Sickle New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    181
    использую в своей программе сабж. элемент списка состоит из двух двойных слов: содержимое и указатель на следующий элемент. элементы создаются функцией GlobalAlloc. по окончании работы программы список бросается в файл, а при старте восстанавливается.

    вот при восстановлении большого списка из файла (сотни тыс. элементов) процесс этот растягивается на оччень продолжительное время... можно ли както оптимизировать этот процесс?
     
  2. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Вместо GlobalAlloc использовать HeapAlloc.



    Ещё быстрее - для каждого списка использовать отдельный Heap объект и когда надо освободить память не надо вызывать HeapFree на каждый елемент списка а просто удалить весь Heap объект через HeapDestroy.
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Почитать об управлении памятью. Оптимизировать работу с ней и с алгоритмом вообще.
     
  4. Sickle

    Sickle New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    181
    AsmGuru62

    HeapAlloc скорость увеличил, но всеже сотни тысяч вызовов видимо не могут пройти быстро :dntknw:

    использовать свой хип для каждого списка не удобно - размер списка заранее не известен.

    напрашивается решение - выделять области к примеру по 4к по мере заполнения... это сильно усложнит функции добавления и удаления элементов, но другого выходя я не вижу
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Сохранять и читать содержимое всех элементов одним сплошным куском.

    В качестве указателя на элемент использовать не абсолютный адрес следующего элемента списка, а смещение от начала большого куска, который содержит все данные. Т.е. указателем на следующий элемент будет не его абсолютный адрес, а nextEntryOffset

    И можно будет всего один раз использовать VirtualAlloc/ReadFile
     
  6. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Sickle

    Скорость проверялась в DEBUG или в RELEASE Build?

    Heap_xxx API очень медленный в DEBUG.

    Я тестировал свой менеджер против Heap_xxx API - API аллоцирует пол-миллиона блоков в секунду в RELEASE. Не хило однако! Мне удалось побить этот результат на сотню миллисекунд, не более - и только за счёт того, что мой менеджер памяти не годится для multi-threaded access.



    Кстати, почему играет роль неизвестность размера списка? ведь HeapAlloc() безразмерный. Ну начни его с 2-х страниц (8Кб), а там, если надо - Windows поддаст больше - пока хватит памяти.
     
  7. Sickle

    Sickle New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    181
    хм.. я тестировал в DEBUG билде.

    полмилиона говоришь... надо проверить, такая скорость меня вполне устроит!
     
  8. asmasm

    asmasm New Member

    Публикаций:
    0
    Регистрация:
    16 янв 2006
    Сообщения:
    69
    Адрес:
    Uzbekistan
    Могу для masm32 кинуть
     
  9. asmasm

    asmasm New Member

    Публикаций:
    0
    Регистрация:
    16 янв 2006
    Сообщения:
    69
    Адрес:
    Uzbekistan
    могу для masm32 кинуть исходник, на моем 256 мГц

    100.000.000 dword'ов пушит секунды за 4.

    Размер указывать требуется.

    Тестировал вот так:

    newobject ASet

    mov ecx,10000000

    l1:

    method esi,ASet,aPush,ecx

    loop l1
     
  10. asmasm

    asmasm New Member

    Публикаций:
    0
    Регистрация:
    16 янв 2006
    Сообщения:
    69
    Адрес:
    Uzbekistan
    извиняюсь , описка, 10.000.000 dword'ов
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Sickle

    А в чем вообще смысл использования односвязного списка большого размера, да еще загружаемого из файла. Минусы очевидны: 1) неэффективное использование памяти - на 4 байта "содержимого" приходится еще 12 байт обслуги (4 на next + 8 заголовок блока кучи), 2) лишние тормоза как при загрузке, так и при работе со списком. А в чем плюсы ? Не проще ли использовать массив с VirtualAlloc'ом или нужна вставка элементов в середину списка ?

    Резервирование диапазона адресов в несколько мегабайт "каши не просит", т.е. памяти не занимает и на фоне доступных 2Гб это капля в море. А насчет "сильно усложнит функции добавления и удаления элементов" это большое преувеличение если элементы добавляются только в конец или\и в начало списка, по крайней мере это будет заметно быстрее и намного экономнее HeapAlloc

    Если все же нужен список, то лучше использовать вариант со смещениями, предлагаемый cresta
     
  12. Sickle

    Sickle New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    181
    вобщем, удалось добиться приличной скорости. дело в том, что при загрузке таблицы из файла я использовал функцию добавления элемента, в которой происходит контроль на дублирующиеся элементы (если такое значение в списке есть, то оно не добавляется). естественно, это требует просмотра всего списка. сделал отдельную функцию добавления без контроля - скорость вполне устраивает. пришлось дополнительно хранить указатель на последний элементы списка, но это ерунда.



    leo

    возможно я приду к такой организации, действительно, список довольно прожерливая структура...
     
  13. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898


    глянь на деревья поиска, или хеш таблицы. Если использовать с умом, можно оччень ускорить.