2010-11-09 60 views
2

我想知道使用WeakRef处理大型数据集的开销是多少?Ruby中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之后,它可以被垃圾回收以释放一些内存。

这种情况的开销是多少?任何替代品?

回答

1

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

取而代之的是设置一个迭代器(响应each的对象),它将数据加载到块中。

+0

只要使用'huge'变量,将数据加载到块中仍将保留所有对象。 – 2010-11-10 07:30:34

+0

但是你的过程是迭代的,所以你不需要在存储器中存储整个'巨大',对吧? – glebm 2010-11-10 22:29:54

+0

对于这种情况是正确的。 – 2010-11-13 03:52:28

2

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

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

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