【问题标题】:python: fast dict lookup from diskpython:从磁盘快速查找字典
【发布时间】:2017-07-16 15:15:18
【问题描述】:

我有一本大字典(100 万键),格式如下:

{
    key1: {
        file1: [number_list1],
        file7: [number_list2],
        file10: [number_list3],
        ...
    }
    key2: {
        file1: [number_list4],
        file5: [number_list5],
        file2: [number_list6],
        ...               
    }
    ...
    ...
}

由于各种限制,在构建它之后,我无法将它保存在内存中,而不得不以腌制形式将其转储到磁盘上。但是,我仍然希望从磁盘快速查找任何一个键。

我的想法是将大字典分成更小的块(大约 0.5-1MB)。这需要一个额外的 key:chunk 映射,但允许我在查找期间只加载必要的块。我想出了以下算法:

  def split_to_pages(self, big_dict):
    page_buffer = defaultdict(lambda: defaultdict(list))
    page_size = 0
    page_number = 0
    symbol2page = {}
    for symbol, files in big_dict.items():
        page_buffer[symbol] = files
        symbol2page[symbol] = page_number
        page_size += deep_sizeof_bytes(files)
        if page_size > max_page_size:
            save_page_to_file(page_number, page_buffer)
            page_buffer.clear()
            page_size = 0
            page_number += 1
    if page_size > 0:
        save_page_to_file(page_number, page_buffer)

此解决方案对于静态字典表现良好。但是,由于它代表一个动态实体,因此很可能在操作期间将新键引入或从 dict 中删除。为了反映这种变化,我的解决方案需要从头开始对整个 dict 进行分区。有没有更好的方法来处理这种情况?我有一种感觉,这是一个我不知道的常见问题,并且已经针对此问题提出了更好的解决方案。

编辑:

我尝试了shelve,对于一个小型数据库(2k 键)大约需要 0.5 秒的键查找时间,这非常慢。我上面描述的半生不熟的分页算法大约是 0.01 秒。 sqlite3 为 100 万个键表做了 0.4 秒的查找时间,我怀疑 mongo 会更快。我的用例开销太大。我想我会继续我自己的分区数据库实现。

【问题讨论】:

  • 我猜这就是发明数据库的原因?
  • 同意。您可以尝试使用redismongoDB 或其他一些 NoSQL 存储。
  • 你可以试一试tinydb。不知道它可以处理多少数据。
  • 我知道数据库,我认为我不必走那条路,因为这对我的应用程序来说有点矫枉过正。我想别无选择。
  • 在使用数据库之前,先试试shelve模块

标签: python dictionary


【解决方案1】:

尝试用于 python 的磁盘键值对解决方案。查看我的项目 RocksDict,它是解决您问题的有效方法:https://github.com/Congyuwang/RocksDict。它比 dbm 快得多,因此比 shelve 快得多,因为它是基于 dbm 的。如果你想尝试 RocksDict,请使用pip install rocksdict

【讨论】:

  • 当链接到您自己的网站或内容(或您附属的内容)时,您must disclose your affiliation in the answer 以免被视为垃圾邮件。根据 Stack Exchange 政策,在您的用户名中包含与 URL 相同的文本或在您的个人资料中提及它不被视为充分披露。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
相关资源
最近更新 更多