2014-01-19 4 views
2

У меня есть конкретное использование HashMap, где он просто хранит несколько записей (обычно менее 5-10) для ключей String. Мне просто нужно добавлять записи, получать их по ключевым словам, а иногда итерировать набор записей. Записи никогда не удаляются в течение срока действия карты. У меня есть некоторая операция, когда 5-6 таких меньших карт необходимы и распределяются каждый раз при использовании одного пользователя, то есть в запросе.Оптимизированная Java-карта/Словарь для небольшого количества записей без удаления

Я использую HashMap для этого. Однако, интересно, есть ли более оптимизированная реализация Map-подобной структуры, которую я мог бы использовать для этого? Например, тот, который будет выделять меньше места и может быть быстрее для небольшого количества элементов. Или HashMap просто достаточно хорош?

Обратите внимание, что я не настаиваю, чтобы следовать за интерфейсом Map.

Моих мысли идут в направление массива спинок карты, что-то вроде этой реализации, что привлекло мое внимание от JetBrains: SmartFMap (непреложной карты оптимизированы для хранения нескольких записей с относительно редких обновлений, как они говорят).

Кто-нибудь знает о таких альтернативных реализациях, которые были бы хорошими заменами HashMap?

ADDON

Моя первоначальная идея заключается в том, что сказал @Evgeniy Дорофеев в своем ответе, чтобы иметь отсортированный массив записей и использовать бинарный поиск, но с следующей модификацией. Поскольку мне нужно добавить элементы в эту коллекцию и предотвратить повторное создание массива, я думал об использовании массива с некоторыми пустым пространством. Первый элемент добавляется, например, в середине массива, второй элемент добавляется в середине оставшейся половины (ниже или ниже, в зависимости от порядка сортировки). Если начальный размер такого массива хорош, мы можем (в основном) предотвратить воссоздание этого массива и по-прежнему иметь возможность бинарного/радиального поиска.

+3

Почему вы хотите микро-оптимизацию, если у вас нет более 10 предметов. если вы не имеете дело с миллионами записей данных, то, что вы думаете, не достойно. это может даже не помочь вам получить оптимизацию 1ns – Reddy

+0

Для меня это весело, сложно, и я мог бы узнать что-то новое. Мне нравится задавать вопросы по умолчанию. И если я нахожу код, который быстрее на 1ns и занимает 1 байт меньше памяти, я пойду с ним - вот только я :) – igr

ответ

0

Вы можете сделать собственную карту на основе массива

Object[][] map = new Object[3][]; 
    map[0] = new Object[] {k1, v1}; 
    map[1] = new Object[] {k2, v2}; 
    map[2] = new Object[] {k3, v3}; 
    Arrays.sort(map); 

как искать

int i = Arrays.binarySearch(map, key); 
Object value = map[i]; 
+0

Смотрите мой аддон. Это была моя первоначальная идея, за исключением того, что я не знаю в начале, сколько предметов будет, поэтому мне нужно иметь функцию «положить» (вставить). См. Мой аддон, как предотвратить перемещение массива. – igr

+0

Также связан с [этот вопрос] (http://stackoverflow.com/questions/360040/which-is-faster-hash-lookup-or-binary-search). Другими словами, будет ли это быстрее, чем поиск? – igr

+1

Я не думаю, что это решение будет быстрее, единственным преимуществом является то, что он потребляет меньше памяти. –

2

считается Вы используете Trie?

Это обеспечит почти такую ​​же сложность, как и ваша хэшмап, чтобы получить предмет. Но в некоторых случаях это будет быстрее. Например, со следующими строками: hello, world, house, foo, bar, balloon. Получение значения, связанного с hello, требует только для сравнения двух первых символов, только для world и 3 для bar и balloon. Используя хэш-карту, вы должны вычислить хэш, используя все символы.

+0

Посмотрите, спасибо. – igr

+0

Согласно [this] (http://bannister.us/weblog/2009/12/23/trie-in-java-revisited/), Trie не может превзойти коллекции java. – igr

0

Рассмотрите возможность использования ImmutableMap от Guava. Создание карты с использованием его, как шарм:

Map<String,String> map = ImmutableMap.of("key1", "value1", "key2", "value2"); 

Там еще один вариант, за исключением случаев, когда вам необходимо изменить данные вашей карты. Вы можете использовать EnumMap от JDK. Это немного быстрее, чем HashMap.

+0

Thanx, однако, мне не нужна неизменяемая карта, так как мне нужно вставлять элементы. EnumMap также не может быть выбором, поскольку ключи не перечислены, просто строки. – igr

+0

Я проверил, и ImmutableMap от Guava делает обычную линейность для каждого поиска. Так что это может быть достаточно хорошо, если вы можете создать неизменяемую карту. – stokito

-1

Вы можете использовать java.util.IdentityHashMap, если используете ключи идентификации. Он немного легче java.util.HashMap.

+0

Обратите внимание, что IdentityHashMap пытается сделать равным по ссылке, а не по значению ключей. Поэтому он не применим к строкам, только вы пытаетесь сделать интернирование строк, что может замедлить производительность. – stokito

+0

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

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