Ruby中WeakRef的成本是多少?

时间:2010-11-09 19:29:31

标签: ruby data-structures memory-management weak-references

我想知道使用WeakRef处理大数据集的开销是多少?

我想要执行的任务是这样的:

huge = get_array_of_weak_refs # 100000000 entries or more :)
result = huge.length * huge.inject(0) { |accum, it| accum += it.total } # much more complicated, just a sample

假设get_array_of_weak_refs不耗时且复杂度O(1)。因此,唯一关心的是huge数组的内存大小。

我现在也不关心计算result的时间。

如果huge是正常数组,那么当然它可能不适合内存。

但是如果将WeakRef用作该数组的元素会有帮助吗?因此,在我们遍历元素x之后,可以对其进行垃圾回收以释放一些内存。

此方案的开销是多少?任何替代方案?

2 个答案:

答案 0 :(得分:2)

WeakRef的成本可能非常高。 WeakRef扩展了Delegator类,在1.8实现中,Delegator对象非常繁重。每次实例化一个Delegator时,包装对象中的每个方法都会被重新定义。使用Delegator包装String将分配~2800个对象并使用~90K的内存。这使得WeakRef在许多情况下无法使用,因为它们创建起来非常慢,并且可能会使用更多内存来指向它们所指向的对象。

在1.9 Ruby代码中已修复了Delegator,但是,有一个错误,WeakRef可能最终指向错误的对象,因此它们的使用是不安全的。

如果您想使用弱引用,可以使用ref gem(https://rubygems.org/gems/ref)。这个gem将开销降低到每个引用的<1K内存。如果您使用Jruby或Rubinius,实现效率会更高。

答案 1 :(得分:1)

为什么你会在这里使用弱引用?他们没有帮助,也不是为这种情况设计的。

而是设置一个迭代器(响应each的对象),以块的形式加载数据。