Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在Ruby中将数组解构为数组_Arrays_Ruby_Memory - Fatal编程技术网

Arrays 在Ruby中将数组解构为数组

Arrays 在Ruby中将数组解构为数组,arrays,ruby,memory,Arrays,Ruby,Memory,假设我有两个相当大的数组,a和b 我想要b=a+b,但我并不真的需要a,我更愿意保存内存,以避免交换 我考虑过简单地使用: b.unshift( *a.slice!(0..-1) ) 但上述方法的缺点是在程序完成之前仍保留a的副本。另一种选择是: while ! a.empty?() do b.unshift( a.pop() ) end 虽然不够优雅,甚至可能更慢(这是迭代,我不知道*操作符的工作速度有多快,可能是在较低的级别),但这将中间内存占用保持在最小 有更优雅的吗

假设我有两个相当大的数组,
a
b

我想要
b=a+b
,但我并不真的需要
a
,我更愿意保存内存,以避免交换

我考虑过简单地使用:

b.unshift( *a.slice!(0..-1) )
但上述方法的缺点是在程序完成之前仍保留
a
的副本。另一种选择是:

while ! a.empty?() do 
       b.unshift( a.pop() )
end
虽然不够优雅,甚至可能更慢(这是迭代,我不知道
*
操作符的工作速度有多快,可能是在较低的级别),但这将中间内存占用保持在最小

有更优雅的吗

有更优雅的吗

同时使用
unshift
pop

a = [1,2,3]
b = [4,5,6]

b.unshift(*a.pop(a.size))

p a, b
# []
# [1, 2, 3, 4, 5, 6]
或者如果您不想使用
*

a = [1,2,3]
b = [4,5,6]

b.unshift(a.pop(a.size)).flatten!

p a, b
# []
# [1, 2, 3, 4, 5, 6]

不能保证分配给
a
的内存会因为删除了所有元素而释放。大多数动态阵列系统都会随着阵列大小的增加进行分配,这是一个很难做到的必要条件,但当涉及到减小大小时,会更加轻松

最好的方法是执行
b+=a
,让
a
超出范围,然后让垃圾收集器对其进行排序


除非您能够生成一个具体的基准测试,表明您的复杂方法工作得更好,但由于splat操作将创建需要收集的额外垃圾,因此可能不会这样做,否则您应该做最简单的工作。

关于
b=a.concat(b)呢
?当您逐个添加元素时,您如何知道ruby不会分配一个
的N个副本(从而浪费内存)?如果您确实关心内存,则需要对代码进行内存配置,并查看每个变量分配了多少对象。@Stefan那么它将是
b=a.concat(b);a=[]
b.unshift(*a)相同;a=[]
。我相信这不是@user1134991所要求的。这可能会比最初的尝试产生更多的垃圾,所以请注意。@tadman“可能”?你不太明白这是怎么回事,是吗?来,让我给你解释一下
a.pop(a.size)
将返回整个数组
a
,还将从数组
a
中删除所有元素。内存的变化是由Ruby的实现决定的。答案中描述的两种变体在使用默认Ruby时都完全释放了array
a
的内存。这“可能”不是你应该向任何人解释的方式,特别是那些回答了数千个Ruby问题的人。我之所以这么说,可能是因为不同的实现,甚至不同版本的Ruby在如何处理这一问题上都存在差异,但这绝不是一个保证“更好”的解决方案。内存分析这些代码片段和OP的代码片段将有助于说服读者,这有时确实表现得更好。乍一看,这两个代码段至少分配了一个新的
a.size
数组。与问题中的代码大致相同。我认为
concat
unshift
都知道新数组的长度。他们都使用
RARRAY_LEN()
来计算,有时MRI根本不会释放任何内存(它的堆只会增长,永远不会缩小)。我想现在好多了。:)@SergioTulentsev啊,1.8天,我们不得不从后面把它们射出去,因为它们太胖太老了。是不是只有1.8天?我的记忆很模糊,但我很确定1.9也是这样运行的。@SergioTulentsev 1.8太糟糕了,以至于存在“EnterpriseRuby”来解决这个问题。1.9有了很大的改进,2.0有了很大的改进。