Ruby 1.9.3和mac堆栈大小问题

时间:2012-04-15 13:26:52

标签: ruby macos recursion stack-overflow depth-first-search

几天前,我在巨大的图形上运行Kosaraju's algorithm时遇到了问题(几乎一百万个顶点和六百万个边缘)。问题出现在算法的DFS (Depth First Search)部分,这是一种反复意义 - 堆栈级别太深。我在Ruby中实现了算法,我使用的Ruby版本是1.9.3。

为了检查堆栈大小,我决定运行简单的过程:

def r n
  p n
  r n+1
end

r 1

表示终止前的堆栈大小。我用了

ulimit -a

命令检查堆栈大小和

ulimit -s 32768     # Seems like this is the maximum stack size for mac OS
ulimit -s unlimited # => Invalid argument error

更改堆栈大小。即使我改变了堆栈大小后r-procedure也显示了相同的数字 - 8193.我将Ruby更改为1.8.7后,最后一个数字变为19177。

最终我发现一个朋友使用Ubuntu和堆栈大小是无限的。我成功运行了Kosaraju的算法。

我怎么能在mac上做到?

2 个答案:

答案 0 :(得分:0)

更改堆栈大小限制的正确语法是:

ulimit -S -s 32768

在OS X 10.7.3上ulimit -S -s unlimited将限制设置为65532。

答案 1 :(得分:0)

除了OS X ulimit值之外,Ruby程序中的堆栈大小可以由以下环境变量控制:RUBY_THREAD_VM_STACK_SIZERUBY_THREAD_MACHINE_STACK_SIZERUBY_FIBER_VM_STACK_SIZERUBY_FIBER_MACHINE_STACK_SIZE 。您可以在irb会话中检查默认值:

RubyVM::DEFAULT_PARAMS
=> {:thread_vm_stack_size=>1048576,
    :thread_machine_stack_size=>1048576,
    :fiber_vm_stack_size=>131072,
    :fiber_machine_stack_size=>524288}

因此,如果要将VM堆栈大小更改为2097152,例如:

RUBY_THREAD_VM_STACK_SIZE=2097152 ruby script.rb

但是,在这种特殊情况下,我在Ruby中实现了相同的算法并遇到了同样的问题,并且增加堆栈大小还不够。对我有用的解决方案是在没有递归的情况下实现算法。