可以分配给变量的最低内存占用对象是多少?
我想创建一个hash
但我只对keys
感兴趣。 因此,我希望values
具有最小的内存占用 。 什么是最适合分配的对象?
-
nil
? - 一个很短的符号,如
:a
? - 甚至更小的东西?
以下内容适用于官方Ruby实现。 在这方面,其他实现可能不同。
nil
, true
, false
和Fixnum
是在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
是立即值( nil
, true
, false
或Fixnum
),则值将仅保存指向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
简而言之,一种万无一失的方法是使用false
, true
, nil
, Fixnum
或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
。 为简单起见,它使用true
作为值。