Is there an easier alternative to array?

I need to create an array with 3 billion boolean variables. My memory is only 4 GB, so I need this array to be very dense (no more than one byte per variable). Theoretically, this should be possible. But I found that Ruby uses too much space for one boolean variable in the array.

ObjectSpace.memsize_of(Array.new(100, false)) #=> 840 

This is more than 8 bytes per variable. I would like to know if there is an easier implementation of C-arrays in Ruby.

Besides the small profile, I also need each logical array to be fast, because I need to flip them as soon as possible on demand.

+5
source share
2 answers

Ruby does not work very well, especially in memory usage. Like others, you must put your logical numbers in numbers. You will lose a lot of memory due to ruby ​​“objectivity”. If this is a bad scenario for you, you can store in long strings and store the strings in an array, losing less memory.

http://calleerlandsson.com/2014/02/06/rubys-bitwise-operators/

You can also implement your own stone in C ++, which, of course, can use bits and doubles, losing memory. And the doubling array means 64 gates in each position, which is more than enough for your application.

Extremely large objects are always a problem and will require a lot from you to simplify work with a large collection of objects. Of course, you need to at least implement some method in order to hold some position in the array of objects that store more than one Boolean, and the other to flip them.

0
source

The next class may not be exactly what you are looking for. It will store 1 or 0 in the array using bit and shift. The default entries are 0. If you need three states for each entry, 0, 1, or zero, then you will need to change it to use two bits for each entry, not one.

 class BitArray < Array BITS_PER_WORD = 0.size * 8 MASK = eval("0x#{'FF' * (BITS_PER_WORD/8)}") - 1 def []=(n, value_0_or_1) word = word_at(n / BITS_PER_WORD) || 0 word &= MASK << n % BITS_PER_WORD super(n / BITS_PER_WORD, value_0_or_1 << (n % BITS_PER_WORD) | word) end def [](n) return 0 if word_at(n / BITS_PER_WORD).nil? (super(n / BITS_PER_WORD) >> (n % BITS_PER_WORD)) & 1 end def word_at(n) Array.instance_method('[]').bind(self).call(n) end end 
0
source

All Articles