2013-12-18 6 views
2

Как я сейчас играю с огромным количеством строк (посмотрим на другой вопрос: VBA memory size of Arrays and Arraylist) Я использовал скриптовый словарь только для функции доступа с ключом, который у него есть. Все выглядело отлично, за исключением того, что это было то, как медленно загружать строки и что он использует много памяти. Для примера из 100 000 строк длиной 128 символов диспетчер задач показал в конце суб примерно 295 МБ, а при установке словаря = ничего не осталось 12 МБ в Excel. Даже учитывая внутреннее преобразование строк в Unicode 128 * 2 * 100,000 дает 25,6 МБ! Может кто-то объяснить эту большую разницу?Как строки хранятся в структуре словаря VBA?

+1

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

+0

Дорогой Роджер, в таких больших размерах еще несколько МБ не представляют интереса. В любом случае, если я решит перейти к решению с хеш-таблицей, я снова собираюсь использовать массивы с одинаковой проблемой размера из-за представления Unicode. Представьте, что эти строки являются хеш-кодами (SHA512) более длинных строк с размерами более 2500 символов – Demetres

ответ

5

Вот вся информация, я мог бы найти на Scripting.Dictionary:

According to Eric Lippert, который написал Scripting.Dictionary «фактическую реализацию общего словаря является расширяемым хэшированием-с-цепочки алгоритма, повторяет хеширование, когда таблица становится слишком полной ». (Из контекста ясно, что он имеет в виду Scripting.Dictionary). Википедия article on Hash Tables - это довольно хорошее представление о вовлеченных концепциях. (Here - это поиск в блоге Эрика для Scripting.Dictionary, он иногда упоминает об этом)

В принципе, вы можете представить Хэш-таблицу как большой массив в памяти. Вместо того, чтобы хранить ваши строки непосредственно индексом, вы должны предоставить ключ (обычно строку). Ключ получает «хэшированный», т. Е. Согласованный набор алгоритмических шагов применяется к ключу, чтобы хрустнуть его в число от 0 до текущего максимального индекса в таблице хешей. Этот номер используется в качестве индекса для хранения вашей строки в хеш-таблице. Поскольку один и тот же набор шагов применяется каждый раз, когда ключ хэшируется, он каждый раз приводит к одному и тому же индексу, то есть если вы просматриваете строку по ее ключу, нет необходимости искать в массиве, как обычно.

Хеш-функция (которая преобразует ключ в индекс в таблицу), предназначена для того, чтобы быть как можно более случайным, но каждый раз через два клавиши могут хрустнуть до того же индекса - это называется столкновением. Это обрабатывается путем «цепочки» строк вместе в связанном списке (или, возможно, с более доступной для поиска структурой). Поэтому предположим, что вы попытались найти строку в таблице Hash с помощью ключа. Ключ хэширован, и вы получаете индекс. Глядя в массив на этот индекс, он может быть пустым слотом, если ни одна строка с этим ключом не была добавлена, или это может быть связанный список, содержащий одну или несколько строк, ключи которых сопоставлены с этим индексом в массиве.

Вся причина для того, чтобы перейти к приведенным выше деталям, состоит в том, чтобы указать, что таблица хешей должна быть больше, чем количество вещей, которые она будет хранить, чтобы сделать ее эффективной (за некоторыми исключениями, см. Perfect Hash Function). Таким образом, большая часть накладных расходов, которые вы увидите в таблице Hash, - это пустые части массива, которые должны быть там, чтобы сделать хэш-таблицу эффективной.

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

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

Если я найду что-нибудь еще, я добавлю его здесь ...

+0

Отличный ответ Blackhawk! Мой вопрос был выяснен, и вы дали мне пищу для дальнейших мыслей. Я все еще открою вопрос, на всякий случай ... – Demetres

Смежные вопросы