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

jua*_*tas 1 ruby arrays benchmarking hashmap

这是我的剧本

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
Run Code Online (Sandbox Code Playgroud)

为什么n=100000我得到:

stack level too deep (SystemStackError)
Run Code Online (Sandbox Code Playgroud)

?

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

And*_*all 7

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

相反,只需将未展平的,未展开的映射数组传递给Hash.[],因为它接受了恰好并给出了相同(正确)的结果(没有SystemStackError):

Hash[array.map { |s| [s.id, s] }]
Run Code Online (Sandbox Code Playgroud)

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

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