我想知道使用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
之后,可以对其进行垃圾回收以释放一些内存。
此方案的开销是多少?任何替代方案?
答案 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
的对象),以块的形式加载数据。