2010-01-19 2 views
14

Я ищу очень компактный способ хранения плотной битрейты переменной длины в Java. Прямо сейчас, я использую BitSet, но, похоже, он использует в среднем 1.5 * n бит пространства для хранения бит-вектора размера n. Как правило, это не проблема, но в этом случае битрейты, которые хранятся, являются довольно значительной частью области памяти приложения. Таким образом, это действительно помогло бы получить их немного меньше.Очень компактный Bitarray в Java

Пространство требует BitSet, как представляется, в связи с тем, что массив длинных позиций используется для резервного структуры данных имеет тенденцию в два раза каждый раз, когда он расширен, чтобы держать больше битов:

// BitSet's resizing code 
private void ensureCapacity(int wordsRequired) { 
    if (words.length < wordsRequired) { 
    // Allocate larger of doubled size or required size 
    int request = Math.max(2 * words.length, wordsRequired); 
    words = Arrays.copyOf(words, request); 
    sizeIsSticky = false; 
    } 
} 

Я мог бы написать моя собственная альтернативная реализация BitSet, которая более консервативно масштабирует структуру данных. Но мне бы очень не хотелось дублировать функциональные возможности, которые уже есть в стандартных библиотеках классов, если мне это не нужно.

+1

мне было бы трудно представить, что это будет в стандартной библиотеке Java. На самом деле это не так. Бьюсь об заклад, вы можете найти стороннюю библиотеку. – Pace

+0

Я думаю, что в вашем случае обычная реализация будет лучшей ставкой. – cx0der

ответ

20

Если вы создаете BitSet, используя конструктор BitSet(int nbits), вы можете указать емкость. Если вы угадаете, что емкость неправильная, и перейдите, она удвоит размер.

Класс BitSet класс имеет метод trimToSize, который является private и вызывается writeObject и clone(). Если вы клонируете свой объект или сериализуете его, он будет обрезать его до нужной длины (предполагая, что класс расширил его с помощью метода securityCapacity).

+8

Yup. Обратите внимание, что вам действительно не нужно использовать скопированную версию. Оригинал обрезается (!). –

+0

Это довольно умно. Благодаря! – dmcer

+0

По крайней мере, в [openjdk source] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/BitSet.java#1085) на GrepCode , оригинал не обрезается в том случае, если вы указали начальный размер, и массив не нужно было расти. – user2357112