Коллекция собственного типа данных или HashMap - PullRequest
0 голосов
/ 17 октября 2011

Я должен хранить информацию для объектов типа «Персона» в структуре данных.Информация может быть, например, простым целочисленным значением.Целочисленные значения будут часто меняться, а также могут меняться лица, для которых хранится информация.Важны две вещи:

  1. Должна быть возможность быстрого поиска, если есть информация, хранящаяся для конкретного человека.
  2. У меня будет огромное количество таких структур данныхтак что память важна.

Есть два разных способа, о которых я могу думать.Прежде всего, я мог бы создать собственный тип данных, который будет содержать как ссылку на человека, так и целое число в качестве полей.Проблема: каждый раз, когда я хочу узнать, есть ли информация для конкретного человека, мне нужно будет просмотреть все объекты и вызвать метод getter для этого человека.Во-вторых, я мог бы использовать HashMap с Person в качестве ключа и Integer в качестве значения.С объектно-ориентированной точки зрения это может быть не так элегантно, как при первой возможности.Кроме того, что еще хуже, HashMaps, по-видимому, потребляют больше памяти, чем простые коллекции (кроме того, мне они очень нравятся, кажется, что часто приходится связывать два разных объекта).Если каждый из них берет, например, килобайт, это будет для меня уже проблематично (мне может понадобиться описанная структура данных около миллиона раз).

Какой вариант вы бы предложили?Или вы можете придумать третью, лучшую возможность?

Спасибо и всего наилучшего

Патрик

Ответы [ 2 ]

1 голос
/ 17 октября 2011

Объект размером в 1 КБ мне кажется немного крутым.Вам понадобится около 256 полей int для достижения этого размера.

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

При быстром взгляде на источник (независимо от размера самого объекта карты) у каждого объекта Entry карты есть int и 3 ссылки, так что на 32-битной виртуальной машине будет 16 байтов;если у вас есть 20 полей int (80 байт) в объекте Person и ключ int в качестве ключа, общий объем памяти для вашего ключа Entry + Person + int будет составлять около 100 байт.В этих условиях вам понадобится около 100 МБ на миллион человек с 20 полями int (это слишком много?)

Что касается самой информации, вы можете сделать несколько оптимизаций:

  • Возможно, одного байта будет достаточно для возраста человека (к сожалению, мы не переживаем 127 лет: P).Подумайте о значениях данных, которые вам нужны, и достаточно ли байта или короткого замыкания.
  • Если вам понадобится имя человека вместо того, чтобы хранить его как одну строку, рассмотрите строку [] сразличные имена, таким образом, вы используете преимущества константы String, и любые повторяющиеся имена будут иметь только один экземпляр в jvm.
  • Хотя это не всегда так (это зависит от реализации jvm), в большинстве случаев логическое значение составляет 32 бита, поэтому, если вы действительно требуете памяти и у вас много логических полей, используйте один байт или короткое поле и замаскируйте его.Вы можете получить 8 «булевых» байтов и 16 коротких.

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

0 голосов
/ 17 октября 2011

Я не уверен, почему вы думаете, что HashMap менее элегантен, чем то, что вы написали (но тогда я не знаю, насколько удивительны ваши навыки программирования).Может быть, вы имеете в виду, что HashMap имеет больше методов, чем вам нужно.HashMaps предназначены для быстрого поиска и повышения эффективности памяти (в отличие от TreeMaps, которые устанавливают приоритет сортируемости).Что касается эффективности памяти, вы проверили, как растет память?Может случиться так, что HashMaps выглядят как запоминающие устройства памяти при небольшом количестве элементов по сравнению с другими картами без хэширования, но тогда использование памяти растет очень медленно по сравнению с другими (которые начинаются с малого, но растут большими и быстрыми).КБ на запись кажется немного большим (именно поэтому я думаю, что вы обнаружите, что истинный размер намного меньше, когда вы измеряете с достаточным количеством выборок), но, опять же, возможно, нет, и миллион записей будет означать 1 МБ - действительноВас это беспокоит?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...