Ruby数组与哈希测试中的堆栈级别太深

Posted

技术标签:

【中文标题】Ruby数组与哈希测试中的堆栈级别太深【英文标题】:Stack level too deep in Ruby array vs hash test 【发布时间】:2014-06-21 01:18:54 【问题描述】:

这是我的脚本

require 'benchmark'
require 'ostruct'

Benchmark.bmbm do |x|
  n=10000
  array = n.times.map |i| OpenStruct.new id: i 
  hash = Hash[*(array.map |s| [s.id, s] .flatten)]

  x.report('array') do
    array.find |s| s.id == 100
  end
  x.report('hash') do
    hash[100]
  end
end

为什么n=100000 我明白了:

stack level too deep (SystemStackError)

?

不相关,但是,我是否以最佳方式构建哈希?

【问题讨论】:

哈希查找总是比Array.find 快,而OpenStruct 不是正确的使用方法,因为它使用method_missing 来构建其属性 @bjhaid 我认为任何基准测试都不一定是“愚蠢的”。有什么更好的方法可以让某人发现并向自己证明哈希查找更快? 正确的做法是什么? @juanpastas 你可以改用简单的Struct 哦,好的,这段代码用于复制我正在处理的其他一些事情,我正在添加属性,我会考虑到这一点。 【参考方案1】:

您将数以万计的参数传递给一个方法,这对于 Ruby 来说太多了,导致堆栈错误。

而只是将未展平、未喷溅的映射数组传递给Hash.[],因为它可以接受并给出相同(正确)的结果(没有 SystemStackError):

Hash[array.map  |s| [s.id, s] ]

顺便说一句,我们可以通过一个简单的测试看到参数计数实际上是问题所在(而不是专门Hash.[]):

def f(*args); end
f(*(1..1000000).to_a)  #<SystemStackError: stack level too deep>

【讨论】:

以上是关于Ruby数组与哈希测试中的堆栈级别太深的主要内容,如果未能解决你的问题,请参考以下文章

堆栈级别也是Ruby on rails

SystemStackError - 堆栈级别太深;在 Rspec 测试中,使用acts_as_audited、Rspec、数据库清理器

Rails:before_save - 堆栈级别太深

如何在应用程序级别加密 ruby​​ on rails 中的完整路由

ruby 将哈希值转换为排序的字符串数组,以便与另一个哈希值进行比较

Ruby 中的关联数组