在 python 中将列表存储在驱动器上的最快方法是什么?

What is the fastest approach of having a list stored on drive in python?

我在 python 中处理(真正的)大数据,对于每个输入,我需要计算一个数字,该数字稍后需要并且可能会更改。所以基本上我有一个整数向量(列表)。

当矢量的大小为O(10^9)或更大时,无法将其装入内存。因此,显然,我需要将它保存到硬盘上的文件中。

所以我需要的是 class 和一对处理包含整数向量的文件的函数。

示例:

class FileVector:
    def __init__(self, file_name)
    def update(self, position, value)
    def read(self, position)

为简单起见,请假设向量的大小是固定且已知的。还让文件在第一次使用 class 之前创建,我们关心的是如何 read/update 它 尽可能快。

所以问题 - 我应该选择哪种文件格式才能最大限度地提高 read/update 速度?或者,是否有任何已经实施的解决方案,最好是在标准库中?我试图找到一些但失败了。

我目前的想法:

请注意,updateread 都不能一次将整个向量加载到内存中。

10^9 是几千兆字节 - 仍然可以放入 RAM,即使在笔记本电脑上也是如此。 Python 像 NumPy 这样的库可以帮助解决这个问题 - 它们提供了专门的数组类型,具有较低的内存占用和一些不错的数学函数。

作为一个真正的大数据,我认为有数百TB或更多...像Hadoop这样的分布式框架通常用于处理这些TB卷的数据。

但是如果你只想要一个基于文件的数组,我会选择 mmap:

import struct
from mmap import mmap

class FileVector:

    number_size = len(struct.pack("<i", 0))

    def __init__(self, file_name, initial_size, default_value=0):
        try:
            self.f = open(file_name, "r+b")
        except FileNotFoundError:
            self.f = open(file_name, "w+b")
            fill = self._number_to_bytes(default_value)
            for i in range(initial_size):
                self.f.write(fill)
            self.f.flush()
        self.m = mmap(self.f.fileno(), 0)

    def close(self):
        self.m.close()
        self.f.close()

    def update(self, position, value):
        self.m.seek(self.number_size * position)
        self.m.write(self._number_to_bytes(value))

    def read(self, position):
        self.m.seek(self.number_size * position)
        return self._bytes_to_number(self.m.read(self.number_size))

    def _number_to_bytes(self, n):
        return struct.pack("<i", n)

    def _bytes_to_number(self, b):
        return struct.unpack("<i", b)[0]

fv = FileVector("data", 10**9)
print(fv.read(1000))
fv.update(1000, -42)
print(fv.read(1000)) # should return -42

但它当然不如 C/C++ 等中的速度快。 - 在我的笔记本上,它设法每秒进行 500 000 次更新或读取,但这可能超过了"normal"数据库可以实现。如果需要并行化,也可以在进程之间共享映射文件。