gpt4 book ai didi

Python mmap - 缓慢访问文件末尾[带测试代码]

转载 作者:太空狗 更新时间:2023-10-30 01:17:54 29 4
gpt4 key购买 nike

我前几天发过一个类似的问题,但是没有任何代码,现在我创建了一个测试代码,希望能得到一些帮助。

代码在底部。

我得到了一些数据集,其中有一堆大文件 (~100),我想非常有效地从这些文件中提取特定行(在内存和速度上)。

我的代码获取相关文件的列表,代码使用 [第 1 行] 打开每个文件,然后使用 [第 2 行] 将文件映射到内存,同时,对于每个文件,我收到一个索引列表并遍历我检索相关信息(本例为 10 个字节),如下所示:[第 3-4 行],最后我用 [第 5-6 行] 关闭句柄。

binaryFile = open(path, "r+b")
binaryFile_mm = mmap.mmap(binaryFile.fileno(), 0)
for INDEX in INDEXES:
information = binaryFile_mm[(INDEX):(INDEX)+10].decode("utf-8")
binaryFile_mm.close()
binaryFile.close()

此代码并行运行,每个文件都有数千个索引,并且每秒连续执行几次,持续数小时。

现在来解决问题 - 当我将索引限制为较小时(意思是 - 当我要求代码从文件开头获取信息时),代码运行良好。但!当我增加索引的范围时,一切都减慢到(几乎)停止并且缓冲区/缓存内存变满(我不确定内存问题是否与减速有关)。

所以我的问题是,为什么我从文件的开头或结尾检索信息很重要,我该如何克服这个问题,以便在不减慢和增加 buff 的情况下即时访问文件结尾的信息/缓存内存使用。

PS - 一些数字和大小:所以我得到了大约 100 个文件,每个文件的大小约为 1GB,当我将索引限制在文件的 0%-10% 时,它运行良好,但是当我允许索引在它停止工作的文件中的任何位置。

代码 - 使用 python 3.5 在 linux 和 windows 上测试,需要 10 GB 的存储空间(创建 3 个文件,每个文件的随机字符串在 3GB 内)

import os, errno, sys
import random, time
import mmap



def create_binary_test_file():
print("Creating files with 3,000,000,000 characters, takes a few seconds...")
test_binary_file1 = open("test_binary_file1.testbin", "wb")
test_binary_file2 = open("test_binary_file2.testbin", "wb")
test_binary_file3 = open("test_binary_file3.testbin", "wb")
for i in range(1000):
if i % 100 == 0 :
print("progress - ", i/10, " % ")
# efficiently create random strings and write to files
tbl = bytes.maketrans(bytearray(range(256)),
bytearray([ord(b'a') + b % 26 for b in range(256)]))
random_string = (os.urandom(3000000).translate(tbl))
test_binary_file1.write(str(random_string).encode('utf-8'))
test_binary_file2.write(str(random_string).encode('utf-8'))
test_binary_file3.write(str(random_string).encode('utf-8'))
test_binary_file1.close()
test_binary_file2.close()
test_binary_file3.close()
print("Created binary file for testing.The file contains 3,000,000,000 characters")




# Opening binary test file
try:
binary_file = open("test_binary_file1.testbin", "r+b")
except OSError as e: # this would be "except OSError, e:" before Python 2.6
if e.errno == errno.ENOENT: # errno.ENOENT = no such file or directory
create_binary_test_file()
binary_file = open("test_binary_file1.testbin", "r+b")




## example of use - perform 100 times, in each itteration: open one of the binary files and retrieve 5,000 sample strings
## (if code runs fast and without a slowdown - increase the k or other numbers and it should reproduce the problem)

## Example 1 - getting information from start of file
print("Getting information from start of file")
etime = []
for i in range(100):
start = time.time()
binary_file_mm = mmap.mmap(binary_file.fileno(), 0)
sample_index_list = random.sample(range(1,100000-1000), k=50000)
sampled_data = [[binary_file_mm[v:v+1000].decode("utf-8")] for v in sample_index_list]
binary_file_mm.close()
binary_file.close()
file_number = random.randint(1, 3)
binary_file = open("test_binary_file" + str(file_number) + ".testbin", "r+b")
etime.append((time.time() - start))
if i % 10 == 9 :
print("Iter ", i, " \tAverage time - ", '%.5f' % (sum(etime[-9:]) / len(etime[-9:])))
binary_file.close()


## Example 2 - getting information from all of the file
print("Getting information from all of the file")
binary_file = open("test_binary_file1.testbin", "r+b")
etime = []
for i in range(100):
start = time.time()
binary_file_mm = mmap.mmap(binary_file.fileno(), 0)
sample_index_list = random.sample(range(1,3000000000-1000), k=50000)
sampled_data = [[binary_file_mm[v:v+1000].decode("utf-8")] for v in sample_index_list]
binary_file_mm.close()
binary_file.close()
file_number = random.randint(1, 3)
binary_file = open("test_binary_file" + str(file_number) + ".testbin", "r+b")
etime.append((time.time() - start))
if i % 10 == 9 :
print("Iter ", i, " \tAverage time - ", '%.5f' % (sum(etime[-9:]) / len(etime[-9:])))
binary_file.close()

我的结果:(从整个文件中获取信息的平均时间比从头开始获取信息慢了近 4 倍,大约 100 个文件和并行计算这种差异变得更大)

Getting information from start of file
Iter 9 Average time - 0.14790
Iter 19 Average time - 0.14590
Iter 29 Average time - 0.14456
Iter 39 Average time - 0.14279
Iter 49 Average time - 0.14256
Iter 59 Average time - 0.14312
Iter 69 Average time - 0.14145
Iter 79 Average time - 0.13867
Iter 89 Average time - 0.14079
Iter 99 Average time - 0.13979
Getting information from all of the file
Iter 9 Average time - 0.46114
Iter 19 Average time - 0.47547
Iter 29 Average time - 0.47936
Iter 39 Average time - 0.47469
Iter 49 Average time - 0.47158
Iter 59 Average time - 0.47114
Iter 69 Average time - 0.47247
Iter 79 Average time - 0.47881
Iter 89 Average time - 0.47792
Iter 99 Average time - 0.47681

最佳答案

你有这个时间差的基本原因是你必须在文件中寻找你需要的地方。您离位置 0 越远,需要的时间就越长。

可能 的帮助是因为您知道所需的起始索引,在文件描述符上查找到该点,然后执行 mmap。或者实际上,为什么首先要使用 mmap - 只需从搜索到的位置读取所需的字节数,然后将其放入结果变量中。

关于Python mmap - 缓慢访问文件末尾[带测试代码],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56629602/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com