3

我正在寻找一些帮助来理解 Python 中大型列表、字典或数组的性能特征。我有大约 100 万个键值对需要临时存储(明年可能会增长到 1000 万个)。它们的键是数据库 ID,范围从 0 到大约 1.1M(有一些间隙),值是浮点数。

我正在计算pagerank,所以我的过程是将每个ID初始化为1,然后在内存中查找并更新大约十次,然后再将其保存回数据库。

  1. 我推测如果我使用数据库 ID 作为数组/列表的索引,列表或数组将是最快的。这将创建一个 gappy 数据结构,但我不明白查找或更新的速度有多快。我也不明白使用arrays而不是列表是否有很大的好处。

  2. 为此使用 dict 非常自然,具有键值对,但我的印象是第一次构建 dict 会非常缓慢且内存密集,因为它会增长以容纳所有条目。

  3. 我还读到 SQLite 可能是使用:memory:标志的一个很好的解决方案,但我还没有深入研究。

无论如何,只是在这里寻找一些指导。在我深入研究时,任何想法都会非常感激。

4

3 回答 3

4

只需从字典开始。即使您在 WinXP 上运行1000 万键也不成问题。但我希望为你着想,你不是:)

字典将更容易编码,并且可能更快地构建和更新,特别是如果您以随机顺序更新值。

通常最好开始编写原型并使用它来识别性能问题。您的瓶颈很可能在您请求数据的任何地方。不输入或从字典中检索它。

于 2013-09-20T16:40:58.623 回答
2

由于键的内置散列,在字典中查找数据需要 O(1) 时间。当然,对于大量数据,会出现需要线性时间来解决的冲突,但是具有 10M 项的 dicts 应该可以正常工作。不要在长列表中搜索数据,因为这将花费线性 (O(n)) 时间。

但是,请考虑使用numpy ,具体取决于您打算如何处理数据。只是为了存储和检索,dicts 是完美的,但是使用 numpy 的向量化而不是使用 loops可以大大加速大量数据的计算。

当您需要执行更复杂的查询(搜索多个键或定义要匹配的条件)时,SQL 就会出现。对于一个简单的键值对,SQL 似乎有点过头了。

于 2013-09-20T18:29:30.273 回答
2

好吧,一般来说,如果你有太多的数据要保存在内存中,你需要使用某种外部存储;如果你所有的数据都适合内存,你不需要做任何花哨的事情。

您可能遇到的最大问题是,如果您拥有的数据多于操作系统在单个进程映像中所允许的数据;在这种情况下,您将需要外部存储。

在这两种情况下,这归结为:使用数据库,无论是否使用 sql。如果它是一个 sql 数据库,您可能希望使用 ORM 来简化它。

但是,在遇到这个问题之前,只需将所有内容存储在内存中,然后序列化到磁盘。我建议使用cPickleORM+sqlite。

于 2013-09-20T19:19:46.897 回答