12 МБ для хранения 120000 слов - это около 100 байт на слово.Вероятно, по крайней мере 32 байта из этого являются строковыми издержками.Если слова в среднем состоят из 10 букв и они хранятся в виде 2-байтовых символов, это составляет еще 20 байтов.Затем есть ссылка на каждую строку в вашем HashSet, которая, вероятно, составляет еще 4 байта.Остальные 44 байта, вероятно, являются издержками на вход и индексирование HashSet, или чем-то, что я не рассмотрел выше.
Самая простая вещь, которую нужно выполнить, - это издержки самих объектов String, которые могут занимать гораздо больше памяти, чемтребуется для хранения фактических данных символов.Таким образом, ваш основной подход заключается в разработке пользовательского представления, которое позволяет избежать хранения отдельного объекта для каждой строки.В ходе этого вы также можете избавиться от накладных расходов HashSet, поскольку все, что вам действительно нужно, - это простой поиск слов, который может быть выполнен с помощью простого двоичного поиска в массиве, который будет частью вашей пользовательской реализации.
Вы можете создать свою собственную реализацию в виде массива типа int с одним элементом для каждого слова.Каждый из этих элементов int будет разбит на подполя, которые содержат длину и смещение, указывающее на отдельный резервный массив типа char.Поместите оба из них в класс, который управляет ими, и который поддерживает публичные методы, позволяющие вам извлекать и / или преобразовывать ваши данные и отдельные символы с учетом строкового индекса и необязательного индекса символов, а также выполнять простой поиск в списке словкоторые необходимы для вашей функции проверки орфографии.
Если у вас есть не более 16777216 символов базовых строковых данных (например, 120 000 строк, умноженных на среднюю длину 10 символов = 1,2 миллиона символов), вы можете взять низкий-упорядочить 24 бита каждого целого и сохранить начальное смещение каждой строки в массиве вспомогательных данных char, взять 8 старших бит каждого целого и сохранить там размер соответствующей строки.
Ваши данные char будут содержать ваши прежние строки без каких-либо разделителей, полностью полагаясь на массив int, чтобы знать, где начинается и заканчивается каждая строка.
Используя вышеупомянутый подход, ваши 120000 слов (в среднем 10 буквкаждый) потребует• 2 400 000 байтов данных массива резервных копий и 480 000 байтов данных целочисленного индекса (120 000 x 4 байта), что в сумме составляет 2 880 000 байтов, что примерно на 75 процентов меньше по сравнению с нынешним объемом в 12 МБ, который вы указали выше.* Слова в массивах будут отсортированы по алфавиту, и ваш процесс поиска может быть простым двоичным поиском в массиве int (извлечение соответствующих слов из массива char для каждого теста), что должно быть очень эффективным.
Если ваши слова оказываются полностью данными ASCII, вы можете сэкономить дополнительно 1 200 000 байтов, сохранив вспомогательные данные как байты, а не как символы.
Это может стать более сложным, если вам потребуется изменить эти строки.Очевидно, в вашем случае (проверка орфографии) вам не нужно (если только вы не хотите поддерживать пользовательские добавления в список, что в любом случае было бы нечастым, и поэтому перезапись данных char и индексов для добавления или удаления слов можетбыть приемлемым).