NSDictionary,NSArray,NSSet和效率

时间:2010-04-24 09:31:26

标签: cocoa nsarray nsdictionary nsset

我有一个文本文件,大约有200,000行。每行代表一个具有多个属性的对象。我只搜索对象的一个​​属性(唯一ID)。如果我要查找的唯一ID与当前对象的唯一ID相同,我将读取对象的其余值。

现在,每次我搜索一个对象时,我只是逐行读取整个文本文件,为每一行创建一个对象,看看它是否是我正在寻找的对象 - 这基本上是最低效的方式做搜索。我想将所有这些对象读入内存,以便以后可以更有效地搜索它们。

问题是,执行此类搜索的最有效方法是什么?是一个20万条NSArray是一个很好的方法来做到这一点(我怀疑)? NSSet怎么样?使用NSSet,是否可以只搜索对象的一个​​属性?

感谢您的帮助!

- Ry

3 个答案:

答案 0 :(得分:13)

@yngvedh是正确的,因为NSDictionary具有O(1)查找时间(正如地图结构所预期的那样)。但是,在进行一些测试后,您可以看到NSSet也有O(1)查找时间。以下是我提出的基本测试:http://pastie.org/933070

基本上,我创建1,000,000个字符串,然后计算从字典和集合中检索100,000个随机字符串需要多长时间。当我运行几次时,该组实际上看起来更快......

dict lookup: 0.174897
set lookup: 0.166058
---------------------
dict lookup: 0.171486
set lookup: 0.165325
---------------------
dict lookup: 0.170934
set lookup: 0.164638
---------------------
dict lookup: 0.172619
set lookup: 0.172966

在您的特定情况下,我不确定这些是否是您想要的。你说你想要所有这些对象都在内存中,但你真的需要它们,还是只需要它们中的一些?如果是后者,那么我可能会读取文件并创建一个对象ID来进行文件偏移映射(即,记住每个对象id在文件中的位置)。然后你可以查找你想要的那些,并使用文件偏移量跳转到文件中的正确位置,解析该行,然后继续。这是NSFileHandle的工作。

答案 1 :(得分:5)

使用NSDictionary从ID映射到对象。即:将ID用作键,将对象用作值。 NSDictionary是唯一支持高效密钥查找的集合类。 (或根本不进行密钥查找)

字典是一种与其他集合类不同的集合。它是一个关联集合(将ID映射到您的案例中的对象),而其他集合只是多个对象的容器。 NSSet保存无序的唯一对象,NSArray保存有序对象(可能包含重复项)。

更新

要避免在阅读条目时重新分配,请使用dictionaryWithCapacity:方法。如果您在阅读之前知道(大致)条目数量,您可以使用它来预先分配足够大的字典。

答案 2 :(得分:4)

200,000个对象听起来可能会遇到内存限制,具体取决于对象的大小和目标环境。您可能要考虑的另一件事是将数据转换为SQLite数据库,然后索引要进行查找的列。这将在效率和资源消耗之间提供良好的折衷,因为您不必将整个集合加载到内存中。