可以分配给变量的最低内存占用对象是多少?

我想创建一个hash但我只对keys感兴趣。 因此,我希望values具有最小的内存占用 。 什么是最适合分配的对象?

  • nil
  • 一个很短的符号,如:a
  • 甚至更小的东西?

以下内容适用于官方Ruby实现。 在这方面,其他实现可能不同。

niltruefalseFixnum是在C级指针内编码的,而所有其他对象都会涉及一个实际指向某处的指针(因此你需要指针的空间消耗加上它指向的空间)。 所以这些对象是内存占用最小的对象。

其中, nil在语义上最有意义。

您可以使用任何您想要的值,只要您使用相同的值即可。

 x = "A string value" h = Hash[ 10000.times.map{|i| [i, x]} ] h2 = Hash[ 10000.times.map{|i| [i, nil]} ] # h takes the same memory as h2 

在上面的例子中, x可以是你喜欢的任何东西。 如果x是立即值( niltruefalseFixnum ),则值将仅保存指向x的指针或值本身。

无论哪种情况,使用的内存都是一样的! 它将是您平台上指针的大小(即0.size字节)。 在C代码中,这对应于VALUE

只是要小心重用相同的对象(即相同的object_id ),而不是每次都创建一个新对象。 例如:

 h3 = Hash[ 10000.times.map{|i| [i, "A string value"]} ] # => h3 will take a lot more space! h.values.map(&:object_id).uniq.size # => 1 h3.values.map(&:object_id).uniq.size # => 10000 

简而言之,一种万无一失的方法是使用falsetruenilFixnumSymbol ,因为符号存储在全局表中。 :hello.object_id在任何地方都是相同的,字符串'hello'只存储一次并在代码中共享所有:hello符号。

 h4 = Hash[ 10000.times.map{|i| [i, :some_symbol]} ] # => h4 will only take as much space as h and h2 h4.values.map(&:object_id).uniq.size # => 1 

仅供参考,内置库Set具有相同的要求,即它仅对键使用Hash 。 为简单起见,它使用true作为值。