2014-02-10 3 views
0

Я работаю на веб-приложения Java, которая использует один большой каскад HashMaps который выглядит следующим образом:HashMap эффективность памяти

HashMap<String, HashMap<String, HashMap<String, Double[]>>> 

Конструкцию после создания, а затем используется только для чтения.

Двойной массив всегда имеет ровно два элемента. Проблема в том, что в конце я использую более 160 байт на двойной массив. Это в 10 раз больше двух двухместных (каждый 8 байт).

Я использовал Runtime.getRuntime().totalMemory(), чтобы посмотреть на использование памяти один раз перед созданием карты и один раз после этих измерений.

Как минимизировать накладные расходы на память?

Есть три возможных решения я считаю прямо сейчас:

  • Используйте другую структуру данных или реализацию Hashmap

  • Именно предвычислять размер каждой карты и установить начальную емкость этого (что?) число + 1 и коэффициент нагрузки до 1,0.

  • Свернуть все ключи в одну строку, добавив их. Это не очень практично для меня, но абсолютно выполнимо. Однако код выглядел бы неплохо.

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

+0

Как выглядят ваши строки и сколько элементов имеет каждый из них в среднем по HashMap? Могут быть некоторые оптимизации, которые вы можете сделать на их основе. – Vitruvius

+1

Можно ли уменьшить это до одного HashMap, получив составной ключ? Возможно, что-то простое, как объединение трех ключевых строк, чтобы сделать один ключ, будет работать. –

+0

@PaulHicks спрашивает упомянутый это возможность. – Vitruvius

ответ

1

Если вы хотите узнать все ключи при вызове get(), я бы предложил создать новый объект для ключа. Помните, реализовать equals() и hashCode()

редактировать:

Использование объекта над каскадный предотвратит ключевые столкновения с certian комбинаций. Если строки «AA», «BB» и «CC» объединены в «AABBCC», то «A», «AB» и «BCC» будут объединены с одним и тем же значением «AABBCC». более читаемый код.

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

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

+0

Почему? Что у вас против «String»? – EJP

+0

, если строки «AA», «BB» и «CC» и объединены с «AABBCC», тогда «A», «AB» и «BCC» будут объединены с одним и тем же значением «AABBCC». Plus it более читабельна, то, что ОП отметил – MadcoreTom

+0

Чтобы избежать непротиворечивости, используйте какой-нибудь странный символ юникода в качестве разделителя. Любой из ваших ключей, которые могут иметь в них армянский язык? – user949300

2

Ваше описание немного запутался, но я бы:

  1. Используйте очень высокий коэффициент нагрузки, такой как 95%.

  2. Сделать double[] вместо Double[]

+0

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

0

Поскольку это звучит как статической таблицы - не изменен - ​​создать класс:

public class MyValues { 
    String key; 
    double value1; 
    double value2; 
} 

Создать объекты и место в массиве MyValues[], а затем сортировать по ключу.

Напишите алгоритм бинарного поиска, чтобы найти значения в таблице. (Это очень простой кусок кода. - 20 строк или около того)

(Использовать регулярные HashMaps для наружных слоев.)

0

Я нашел решение, которое использует около 22 байт на двойной массив со следующими метод:

  • Использование двойной [] вместо Double []
  • Приказываю данные я получаю от первого слоя ключей, и я использовал THashMap из библиотеки Trove. Эта реализация HashMap имеет компактный метод, который уменьшает размер HashMap вплоть до того размера, который требуется для хранения всех элементов, которые он имеет прямо сейчас. Периодически вызывая эту функцию, я смог постоянно держать размер вниз.
Смежные вопросы