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

时间:2013-02-06 18:19:14

标签: ruby

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

  • nil
  • 一个非常简短的符号,例如:a
  • 甚至更小的东西?

2 个答案:

答案 0 :(得分:5)

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

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是直接值(xniltrue或{{},则值仅保留指向false的指针或值本身1}})。

在任何一种情况下,使用的内存都是相同的!它将是您平台上指针的大小(即Fixnum字节)。在C代码中,这对应于0.size

小心重用同一个对象(即同一个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 falsetruenilFixnum,因为符号存储在全球表。 Symbol在任何地方都是相同的,字符串: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作为值。

答案 1 :(得分:2)

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

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

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