在python中使用file.seek()时,通常会将多少字节加载到内存中?

在python中使用file.seek()时,通常会将多少字节加载到内存中?,python,file,hash,size,seek,Python,File,Hash,Size,Seek,我目前正在使用一个4G字节大小的文件作为开放寻址哈希表。 为了读取每个偏移量,我对一个1字节(char)数据使用file.seek()函数。我想使用bucket优化文件的大小(在没有数据的偏移量上节省空间),为了达到最佳优化效果,我想知道在使用file.seek()时,有多少字节被缓存到内存中? 这样,我可以调整存储桶,使文件所需空间减少,但磁盘I/O读取不会增加。file.seek()方法将非常节省内存,但速度也非常慢。不过,您需要按照页面边界对齐所有内容,因此我建议您不要跨越4kib边界 如

我目前正在使用一个4G字节大小的文件作为开放寻址哈希表。 为了读取每个偏移量,我对一个1字节(char)数据使用file.seek()函数。我想使用bucket优化文件的大小(在没有数据的偏移量上节省空间),为了达到最佳优化效果,我想知道在使用file.seek()时,有多少字节被缓存到内存中? 这样,我可以调整存储桶,使文件所需空间减少,但磁盘I/O读取不会增加。

file.seek()
方法将非常节省内存,但速度也非常慢。不过,您需要按照页面边界对齐所有内容,因此我建议您不要跨越4kib边界

如果您使用的是64位处理器,请使用将整个文件映射到内存中,而不是使用
file.seek()
。然后,您可以使用页面大小通常为4kib的规则,从而对齐4kib边界上的所有内容。这肯定比dummily使用
file.seek要快得多;虽然最终可能会消耗更多内存,但操作系统可以根据您的访问模式进行微调


在Python 3上,您将使用
mmap
,如下所示:

# provided that your hashtable is in this file
# and its size is 4 GiB
with open("hashtable", "r+b") as f:
    # memory-map the file, size 0 means whole file
    mm = mmap.mmap(f.fileno(), 0)

    # here mm behaves like 4 billion element bytearray
    # that you can read from and write to. changes
    # are flushed to the underlying file.

    # set 1 byte in the file
    mm[123456789] = 42

    # ensure that changes are written to disk
    mm.flush()

    # close the mapping
    mm.close()
file.seek()
方法将非常节省内存,但速度也非常慢。不过,您需要按照页面边界对齐所有内容,因此我建议您不要跨越4kib边界

如果您使用的是64位处理器,请使用将整个文件映射到内存中,而不是使用
file.seek()
。然后,您可以使用页面大小通常为4kib的规则,从而对齐4kib边界上的所有内容。这肯定比dummily使用
file.seek要快得多;虽然最终可能会消耗更多内存,但操作系统可以根据您的访问模式进行微调


在Python 3上,您将使用
mmap
,如下所示:

# provided that your hashtable is in this file
# and its size is 4 GiB
with open("hashtable", "r+b") as f:
    # memory-map the file, size 0 means whole file
    mm = mmap.mmap(f.fileno(), 0)

    # here mm behaves like 4 billion element bytearray
    # that you can read from and write to. changes
    # are flushed to the underlying file.

    # set 1 byte in the file
    mm[123456789] = 42

    # ensure that changes are written to disk
    mm.flush()

    # close the mapping
    mm.close()

我也鼓励使用
mmap
。您知道是否有某种机制可以在不再需要某些页面时显式卸载它们吗?默认的OS缓存策略不一定适用于特定的OP用例……不幸的是,缓存刷新的具体细节是特定于OS的,需要在Linux上调用
madvise
;当然可以使用<代码> cType < /代码>。我将考虑您的使用MMAP替代品。但不幸的是,我认为这对我没有帮助,因为我正在处理40个文件,如上所述,每个文件的大小可以从100MB到4GB,因此将所有文件加载到内存可能是不可行的,而且我会过多地使用交换分区方式。此外,加载所有文件可能需要很长时间(将所有文件加载到内存大约需要10-30分钟)。关于操作系统,目前代码运行在Windows-7上,但我很快需要在专用的linux(可能是centos)服务器上进行设置。不,他们不会使用swap,而是使用该文件。这也是MongoDB对整个数据库使用的方法(整个数据库始终是mmap映射的)。我也鼓励使用
mmap
。您知道是否有某种机制可以在不再需要某些页面时显式卸载它们吗?默认的OS缓存策略不一定适用于特定的OP用例……不幸的是,缓存刷新的具体细节是特定于OS的,需要在Linux上调用
madvise
;当然可以使用<代码> cType < /代码>。我将考虑您的使用MMAP替代品。但不幸的是,我认为这对我没有帮助,因为我正在处理40个文件,如上所述,每个文件的大小可以从100MB到4GB,因此将所有文件加载到内存可能是不可行的,而且我会过多地使用交换分区方式。此外,加载所有文件可能需要很长时间(将所有文件加载到内存大约需要10-30分钟)。关于操作系统,目前代码运行在Windows-7上,但我很快需要在专用的linux(可能是centos)服务器上进行设置。不,他们不会使用swap,而是使用该文件。这也是MongoDB对整个数据库使用的方法(整个数据库始终被映射)。