Создание эффективной реализации сортированного списка с использованием generics
Сергей Смирнов (Serginio1) Так случилось, что я стал программистом 1С. Все прекрасно в этой среде, за исключением скорости. Эту проблему можно решить только одним способом: прямым доступом к файлам и обработкой результатов на компилируемом языке в памяти. Так, для группирования данных нужны алгоритмы поиска и вставки. И мое сознание, отягощенное бухгалтерским учетом, не нашло ничего лучшего, чем использовать аналог TList (SortedList), представляющий собой динамический массив со свойствами «емкость» и «количество элементов». Упорядоченность в этом массиве поддерживается с помощью компараторов, а при поиске используется алгоритм половинного деления с поиском нужной позиции i по ключу с условием (Items[i]>=Key) AND (Items[i-1]<Key). Если такого ключа нет, то все данные с позиции i переносятся на одну позицию в большую сторону. При этом используются процессорные команды MOVSW и MOVSB, которые выполняются очень быстро. При полном заполнении массива его размер увеличивается либо за счет свободных адресов, следующих за конечным адресом в массиве, либо с помощью выделения нового массива большей емкости с копированием данных из оригинала. Но время шло, и объем группировок вышел за 10000 записей. Мой AMD K6 200 (мощный по тем временам компьютер) начал работать слишком меленно. И не удивительно – количество сдвигаемых элементов в среднем стало равно N2/4, то есть 108. И вот как-то, после очередного обучения бухгалтеров бухгалтерии, пришла мысль. Зачем держать один большой массив, если можно его разбить на множество маленьких? Сказано – сделано. В течение двух минут я создал двухуровневый массив. Первый (верхний) уровень – это массив, элементами которого являются ссылки на массивы нижнего уровня. Второй из уровней (нижний) по сути, состоит из простых динамических массивов. Под простыми понимается то, что память под них выделяется заранее и впоследствии не перезанимается. Фактически этот массив представляет собой структуру, хранящую счетчик элементов и массив пар «ключ-значение». В дальнейшем я буду называть эти динамические массивы листовыми страницами (LeafPage).
Поиск проходил в 2 этапа. Сначала производится поиск массива, в котором может находиться искомый ключ. Для этого с искомым значением сравниваются значение ключей нулевых элементов массивов KeyItems с таким условием, чтобы значение ключа нулевого элемента массива было меньше или равнялось искомому, а значение нулевого элемента следующего массива превышало искомое. Это можно выразить так:
Алгоритм поиска на нижнем уровне аналогичен поиску в одномерном массиве. При полном заполнении KeyItems выделяется новый PLeafIPage, в который копируется половина данных. Ссылка на новый массив вставляется в массив LeafPageArray в позицию на 1 больше текущей. При этом количество кода было менее 100 строк. Такой подход позволил резко сократить объем копируемой памяти – так как количество копируемых элементов никогда не превышает 64. Тем самым удалось избежать замедления работы массива при его росте.
B+-деревья Когда объем группировок начал подходить к миллионам записей, этот алгоритм начал «тормозить» из-за увеличения размера массива верхнего уровня. Проблемы с копированием больших объемов данных вернулись. Чтобы избавиться от этой проблемы, можно применить тот же самый механизм, и разбить массив верхнего уровня на несколько подмассивов. Это приведет к созданию трехуровневого массива, а когда-нибудь, возможно, и четырехуровневого. Так что в принципе есть резон сразу создавать универсальный алгоритм, автоматически увеличивающий количество уровней и строящий дерево. Структура этого дерева включает страницы двух типов – узловые, содержащие массивы ссылок на нижележащие страницы, и листовые, содержащие отсортированные списки данных. Такое дерево называется B+-деревом. Однако разбирать подробно реализацию B+-деревьев в этой статье я не буду.
Популярное: Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (250)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |