是否有更轻量级的阵列替代品?

时间:2015-07-04 15:25:43

标签: arrays ruby

我需要创建一个包含30亿个布尔变量的数组。我的内存只有4GB,因此我需要这个数组非常紧凑(每个变量最多一个字节)。从理论上讲,这应该是可能的。但是我发现Ruby在数组中为一个布尔变量使用了太多的空间。

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

每个变量超过8个字节。我想知道Ruby中是否有更轻量级的C数组实现。

除了一个小的配置文件,我还需要每个布尔这个数组可以快速访问,因为我需要尽快按需翻转它们。

2 个答案:

答案 0 :(得分:0)

Ruby并不是一种表现良好的语言,特别是在内存使用方面。正如其他人所说,你应该把你的布尔值放在数字上。由于红宝石的客观化,你会失去很多记忆。如果对你来说这是一个糟糕的情况,你可以存储到一个很长的字符串中,并将字符串存储在一个数组中,从而减少内存。

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

你也可以在C ++中实现自己的gem,它可以自然地使用位和双精度,减少内存。一系列双打在每个位置意味着64个布尔值,足以满足您的应用。

非常大的对象总是一个问题,需要您实现很多,以便更容易使用大量的对象。当然,你必须至少实现某种方法来在一个存储多个布尔值的对象数组中占据某个位置,而另一个方法则用于翻转它们。

答案 1 :(得分:0)

以下课程可能并不完全符合您的要求。它将使用位和移位将1或0存储到数组中。条目默认为0.如果每个条目需要三个状态,0,1或nil,则需要将其更改为每个条目使用两个位,而不是一个。

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