Python中大型数据结构的性能

Python中大型数据结构的性能,python,arrays,performance,sqlite,data-structures,Python,Arrays,Performance,Sqlite,Data Structures,我想了解Python中大型列表、dict或数组的性能特征。我有大约100万个键值对需要临时存储(明年可能会增加到1000万个)。这些键是范围从0到大约1.1M(有一些间隙)的数据库ID,值是浮点数 我在计算pagerank,所以我的过程是用一个值1初始化每个ID,然后在内存中查找并更新大约十次,然后将其保存回数据库 我的理论是,如果使用数据库ID作为数组/列表的索引,列表或数组将是最快的。这将创建一个gappy数据结构,但我不知道查找或更新的速度有多快。我还不明白使用数组而不是列表是否能带来很大

我想了解Python中大型列表、dict或数组的性能特征。我有大约100万个键值对需要临时存储(明年可能会增加到1000万个)。这些键是范围从0到大约1.1M(有一些间隙)的数据库ID,值是浮点数

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

  • 我的理论是,如果使用数据库ID作为数组/列表的索引,列表或数组将是最快的。这将创建一个gappy数据结构,但我不知道查找或更新的速度有多快。我还不明白使用
    数组而不是列表是否能带来很大的好处

  • 使用dict是很自然的,有键值对,但我得到的印象是,第一次构建dict将非常缓慢,而且内存会非常紧张,因为它会增长到容纳所有条目

  • 我还了解到,使用
    :memory:
    标志,SQLite可能是一个很好的解决方案,但我还没有深入研究过这一点


  • 不管怎样,我只是想在这里寻求一些指导。在我深入研究的过程中,任何想法都将不胜感激。

    从一本字典开始。1000万把钥匙应该不是问题。但为了你的缘故,我希望你不是:)

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

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

    由于内置键,在字典中查找数据需要O(1)个时间。当然,对于大量数据,可能需要线性时间才能解析,但包含1000万项的DICT应该可以正常工作。不要在长列表中搜索数据,因为这需要线性(O(n))时间

    但是,考虑使用取决于你计划用你的数据做什么。dicts仅用于存储和检索,是完美的,但使用numpy的dicts可以大大加快对大量数据的计算


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

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

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

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


    然而,在遇到这个问题之前,只需将所有内容存储在内存中,并序列化到磁盘。我建议使用
    cPickle
    或ORM+sqlite

    如果您想操作一个包含数百万条目的数组,请考虑使用
    numpy
    。至少它将使用大约2-3倍的内存,如果你幸运的话,你可以矢量化操作,从而获得巨大的速度增益。但是,您应该能够使用普通计算机在
    dict
    中处理1000万个键/值对。创建一个大的
    dict
    当然需要时间,但它是一个线性时间操作,因此不会花费大量时间。在我的机器上,构建一个1000万条记录需要1.88秒。它使用了大约700MB的RAM。一个简单的注意事项是:如果以元素对元素的方式使用
    numpy
    ,那么您可能会看到应用程序的速度变慢,因为
    numpy
    每次都必须执行从本机数据类型到python对象的转换,所以当您执行
    array[index]时
    将创建一个新对象等。这对于
    阵列
    模块中的阵列也是如此,因此在决定之前,您应该非常小心并对应用程序进行一些真实的分析。