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数组与哈希测试中的堆栈级别太深的主要内容,如果未能解决你的问题,请参考以下文章
SystemStackError - 堆栈级别太深;在 Rspec 测试中,使用acts_as_audited、Rspec、数据库清理器
如何在应用程序级别加密 ruby on rails 中的完整路由