Какую структуру данных использовать в VB.NET, чтобы по двум символам возвращалось целое число для оптимальной производительности?

Я заканчиваю программу, которая выполняет большое количество вычислений, и пытаюсь оптимизировать самый внутренний цикл.

Вычисление, которое я сейчас рассматриваю, перебирает большое количество пар слов и составляет таблицу количества соответствующих пар символов. Например, одна пара слов может быть:

voice
louse

и тогда пары символов будут (v,l), (o,o), (i,u), (c,s) и (e,e), и все эти пары будут тогда иметь счетчик 1. Если комбинация (v,l) когда-либо снова встретится в другом слове, это увеличит этот счет до двух.

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

Dim data As New Dictionary(of String, Dictionary(of String, Integer))

Используя эту структуру данных, программа должна хешировать две строки для каждого извлекаемого ею целого числа. Для каждой пары символов он должен сначала проверить, находится ли пара в хеш-таблице, и если нет, добавить ее, потребуются еще два хэша. Я также рассматривал одноуровневую хеш-таблицу с ключом, представляющим собой два соединенных вместе символа, поэтому ключ = "vl" и значение = 1, но я читал, что конкатенация строк в VB выполняется относительно медленно.

Итак, мои вопросы:

Насколько быстры словари в VB? Будут ли четыре хэша быстрее, чем один хеш и конкатенация строк (двухуровневая или одноуровневая хеш-таблица)?

Можете ли вы придумать лучшую структуру для хранения такого рода данных, позволяющую быстро добавлять и извлекать их?


person davidscolgan    schedule 11.08.2010    source источник


Ответы (1)


Один из вариантов — использовать Dictionary(Of Integer, Integer). Вы можете преобразовать любой символ .NET Unicode в 16-битное целое число без знака, так как они представляют собой кодовые единицы UTF-16.

Затем вы можете очень легко объединить два 16-битных целых числа без знака в 32-битное целое число. В качестве альтернативы вы можете просто преобразовать каждую единицу кода в 32-битное целое число без знака для начала, а также сдвигать и комбинировать таким же образом :)

В С# я бы просто использовал:

int combination = (((int) char1) << 16) | ((int) char2);

РЕДАКТИРОВАТЬ: Согласно комментарию jeroenh, эквивалент VB:

Dim combination As Integer = (AscW(char1) << 16) Or AscW(char2)
person Jon Skeet    schedule 11.08.2010
comment
Отлично! Это ускоряет вычисления примерно в три раза. - person davidscolgan; 12.08.2010