Автор вопроса: Winand | Web-сайт:winandfx.narod.ru
Нужно отсортировать коллекцию объектов (объект - класс с String полями, по которым и сортируем)
6500 элементов сортируется секунд за 6-7. Решил ускорить и создал индекс - long массив с номерами. По сути сортируется не сама коллекция, а этот массив. И тут я с удивлением обнаружил, что скорость не изменилась вообще.
Почитав http://www.vbaccelerator.com/home/vb/code/techniques/A_Fast_Index-Based_Object_Collection/article.asp узнал что основная проблема коллекций - медленное чтение (а мне как раз все время приходится обращаться к объектам при сортировке). Но предложенная там альтернатива не подходит, т.к. требует дополнительного TLB файла - вся портабельность убивается.
При доступе к элементам коллекции по ключу, а не номеру, скорость сортировки становится 1.6 - 2.6 сек (в зависимости от поля, по которому сортирую). Однако как удалять-то элементы) Ключи же нельзя изменять. Неужто придется делать коллекцию освободившихся ключей.. Подумайте об этом, товарищи! и скажите чонить)
Можно использовать альтернативный язык - типа PowserBasic или PureBasic. Там реальная скорость выполнения. Можно создать отдельную хелпер библиотечку, она будет небольшой (при желании ее можно зашить в программу).
Можно еще посмотреть примеры с Windows API, но там достаточно мутная работа с фунциями памяти.
Sharp, так я и делаю. Проблема коллекций в медленном доступе к элементам, а при сортировке часто приходится производить чтение из коллекции.
Alex, у меня повсеместно в программе copymemory (я даже long массив им сдвигаю) и прочая мутная работа с памятью. Вот только я не видел примеров реализации коллекции объектов на API
Artyom, кажется я справился с ситуацией) ура
7 секунд было при сортировке методом Heap sort, при использовании обращения к элементам коллекции по индексу.
Шаг первый: делаем обращение по ключам, для удобства пишем класс
Option Explicit
PrivateDeclareSub CopyMemory Lib"Kernel32"Alias"RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes&)
IfNot b(p, InStr(1, trck, "/")) Then p = InStr(1, trck, "\")
If p > 1 Then
FormatTrack = Left$(trck, p - 1)
FormatTrack = Format$(FormatTrack, "0000")
Else
FormatTrack = Format$(trck, "0000")
EndIf
EndFunction
Приведенная процедура сортирует одновременно по полю Альбом и Номер трека. И несмотря ни на что делает это за ~0.85с на тех же самых 6546 объектах в коллекции.
В итоге скорость увеличилась чуть ли не в 10 раз от изначальной) круто
Ты бы мог получить 600-кратное увеличение скорости по сравнению с изначальной, если б перешел на дотнет и воспользовался библиотечной функцией List.Sort