我有一个程序,可以存储一个类的多个实例,比如说多达10000个或更多.类实例有几个我不时需要的属性,但它们最重要的一个是ID.

class Document
  attr_accessor :id
  def ==(document)
    document.id == self.id
  end
end

现在,存储数千个这样的对象的最快方式是什么?

我曾经把它们都放进一系列文件中:

documents = Array.new
documents << Document.new
# etc

现在,另一种 Select 是将它们存储在散列中:

documents = Hash.new
doc = Document.new
documents[doc.id] = doc
# etc

在我的应用程序中,我主要需要找出文档是否存在.散列的has_key?函数是否比数组的线性搜索和Document个对象的比较快得多?都在O(n)以内或has_key?甚至O(1)以内.我会看到区别吗?

此外,有时我需要在文档已经存在时添加文档.当我使用数组时,我必须先判断include?,当我使用散列时,我只会再次使用has_key?.问题同上.

你的 idea 是什么?当90%的时间我只需要知道ID是否存在(而不是对象本身!)时,存储大量数据的最快方法是什么

推荐答案

哈希查找速度快much倍:

require 'benchmark'
Document = Struct.new(:id,:a,:b,:c)
documents_a = []
documents_h = {}
1.upto(10_000) do |n|
  d = Document.new(n)
  documents_a << d
  documents_h[d.id] = d
end
searchlist = Array.new(1000){ rand(10_000)+1 }

Benchmark.bm(10) do |x|
  x.report('array'){searchlist.each{|el| documents_a.any?{|d| d.id == el}} }
  x.report('hash'){searchlist.each{|el| documents_h.has_key?(el)} }
end

#                user     system      total        real
#array       2.240000   0.020000   2.260000 (  2.370452)
#hash        0.000000   0.000000   0.000000 (  0.000695)

Ruby相关问答推荐

带有虾Ruby 的动态标题

数组上的Ruby#unionreact 非常奇怪

Ruby:这两种混入模块方法是否等效?

如何替换 ruby​​ 中模式的每个实例?

判断文件是否包含字符串

Ruby数组中的`return`#map

如何将哈希保存到 CSV

为什么在Ruby中用空格分隔的两个字符串连接在一起?

在 Ubuntu 上安装 Ruby 1.9.1?

格式化 Ruby 的漂亮打印

如何通过一组新的给定键更改哈希的所有键

Rake 与 Thor 的自动化脚本?

无法正确自动生成 Ruby DevKit 配置文件

在 Ruby 中取消定义变量

用 Ruby 解析 XML

你能在 Python 的核心类型上修改补丁方法吗?

如何只获取没有命名空间的类名

哪个键/值存储最有前途/最稳定?

Lisp 和 Erlang 原子、Ruby 和 Scheme 符号.它们有多大用处?

如何从字符串创建 Ruby 日期对象?