Сначала рассмотрим память, занятую целыми числами.Вы сказали, что диапазон будет около 0-4000000.24 бита достаточно для представления 16777216 различных значений.Если это приемлемо, вы можете использовать байтовые массивы для целых чисел с 3 байтами на целое число и сэкономить 25%.Вам нужно будет индексировать в массиве что-то вроде этого:
int getPackedInt(byte[] array, int index) {
int i = index*3;
return ((array[i] & 0xFF)<<16) + ((array[i+1] & 0xFF) <<8) + (array[i+2] & 0xFF);
}
int storePackedInt(byte[] array, int index, int value) {
assert value >= 0 && value <= 0xFFFFFF;
int i = index*3;
array[i] = (byte)((value>>16) & 0xFF);
array[i+1] = (byte)((value>>8) & 0xFF);
array[i+2] = (byte)(value & 0xFF);
}
Можете ли вы что-нибудь сказать о распределении целых чисел?Если многие из них уместятся в 16 бит, вы можете использовать кодировку с переменным числом байтов на число (что-то вроде UTF-8 для представления символов).
Далее, подумайте, можете ли вы сэкономить память наСтруны.Каковы характеристики струн?Как долго они обычно будут?Будет ли много строк иметь префиксы?Схема сжатия, адаптированная к характеристикам вашего приложения, может сэкономить много места (как указал falsarella).ИЛИ, если многие строки будут иметь общие префиксы, хранение их в некотором типе поиска может быть более эффективным.(Существует тип дерева, называемый «patricia», который может подойти для этого приложения.) В качестве бонуса обратите внимание, что поиск строк в дереве может быть быстрее , чем поиск по хеш-карте (хотя вы 'Мне нужно провести тестирование, чтобы увидеть, так ли это в вашем приложении).
Будут ли все строки ASCII?Если это так, 50% памяти, используемой для строк, будет потрачено впустую, поскольку Java char
составляет 16 бит.Опять же, в этом случае вы можете рассмотреть возможность использования байтовых массивов.
Если вам нужно только искать строки, а не перебирать сохраненные строки, вы также можете рассмотреть что-то довольно необычное: хеширование строк и сохранение толькохешПоскольку разные строки могут хэшировать одно и то же значение, существует вероятность того, что строка, которая никогда не сохранялась, все равно может быть «найдена» при поиске.Но если вы используете достаточно битов для хеш-значения (и хорошей хеш-функции), вы можете сделать этот шанс настолько бесконечно малым, что он почти наверняка никогда не случится в течение предполагаемой продолжительности жизни вселенной.
Наконец, естьэто память для самой структуры, которая содержит строки и целые числа.Я уже предлагал использовать trie, но если вы решите не делать этого, ничто не будет использовать меньше памяти, чем параллельные массивы - один отсортированный массив строк (по которому вы можете выполнять бинарный поиск, как вы сказали) и параллельный массивмассивы целых чисел.После того, как вы выполните двоичный поиск, чтобы найти индекс в массиве String, вы можете использовать тот же индекс для доступа к массиву array-of-integer.
Если вы строите структуру, если вы решите, чтоSearch Trie - хороший выбор, я бы использовал это напрямую.В противном случае вы могли бы сделать 2 прохода: один для создания набора строк (затем поместить их в массив и отсортировать их), а второй - для добавления массивов целых чисел.