gpt4 book ai didi

arrays - Array#push 导致大数组出现 "stack level too deep"错误

转载 作者:数据小太阳 更新时间:2023-10-29 06:28:37 26 4
gpt4 key购买 nike

我做了两个数组,每个数组有 100 万个项目:

a1 = 1_000_000.times.to_a
a2 = a1.clone

我试图将 a2 插入 a1:

a1.push *a2

这将返回 SystemStackError: stack level too deep

但是,当我尝试使用 concat 时,我没有收到错误消息:

a1.concat a2
a1.length # => 2_000_000

我也没有得到 splat 运算符的错误:

a3 = [*a1, *a2]
a3.length # => 2_000_000

为什么会这样?我查看了 Array#push 的文档,它是用 C 语言编写的。我怀疑它可能在幕后进行一些递归,这就是它导致大型数组出现此错误的原因。这样对吗?对大型数组使用 push 不是一个好主意吗?

最佳答案

我认为这不是递归错误,而是参数堆栈错误。您正在运行参数的 Ruby VM 堆栈深度限制。

问题是 splat 运算符,它作为参数传递给 push。 splat 运算符扩展为百万元素参数列表,用于 push

由于函数参数作为堆栈元素传递,Ruby VM 堆栈大小的预配置最大大小为:

RubyVM::DEFAULT_PARAMS[:thread_vm_stack_size]
=> 1048576

..这就是限制的来源。

您可以尝试以下方法:

RUBY_THREAD_VM_STACK_SIZE=10000000 ruby array_script.rb

..它会正常工作。

这也是您想要使用 concat 的原因,因为整个数组可以作为一个单独的引用传递,然后 concat 将在内部处理该数组。与 push + splat 不同,它将尝试使用堆栈作为所有数组元素的临时存储。

关于arrays - Array#push 导致大数组出现 "stack level too deep"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51995480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com