为什么python中的mmap这么慢?

为什么python中的mmap这么慢?,python,performance,io,mmap,Python,Performance,Io,Mmap,我有一个1GB的二进制示例文件,我把它加载到内存中。在Python3.7和windows上运行基准测试时,mmap相对于readinto的性能严重下降。下面的代码运行一个基准测试。第一个例程使用simplereadinto,将文件的前N个字节读入缓冲区,而第二个例程使用mmap将N个字节读入内存并读取 将numpy导入为np 导入时间 导入mmap 导入操作系统 将matplotlib.pyplot作为plt导入 def mmap_perf(): filepath=“test.bin” file

我有一个1GB的二进制示例文件,我把它加载到内存中。在Python3.7和windows上运行基准测试时,
mmap
相对于
readinto
的性能严重下降。下面的代码运行一个基准测试。第一个例程使用simple
readinto
,将文件的前N个字节读入缓冲区,而第二个例程使用
mmap
将N个字节读入内存并读取

将numpy导入为np
导入时间
导入mmap
导入操作系统
将matplotlib.pyplot作为plt导入
def mmap_perf():
filepath=“test.bin”
filesize=os.path.getsize(filepath)
兆字节=10**6
批量大小=10*兆字节
mview=memoryview(bytearray(文件大小))
批次大小=[]
加载持续时间=[]
对于范围(1,文件大小//批量大小)内的i\U零件:
开始时间=time.time()
以open(文件路径,“br”)作为fp:
#开始=i_零件*批量大小
fp.seek(0)
fp.readinto(mview[0:批次大小*i\u零件])
duration\u readinto=time.time()-开始时间
开始时间=time.time()
以open(文件路径,“br”)作为fp:
长度=(i_零件*批次大小//mmap.ALLOCATIONGRANULARITY+1)*\
mmap.ALLOCATIONGRANULARITY
使用mmap.mmap(fp.fileno(),
偏移量=0,
长度=长度,
access=mmap.access(读取)为mp:
mview[0:i\u零件*批量大小]=mp[0:i\u零件*批量大小]
duration\u mmap=time.time()-开始时间
msg=“{2}MB\nReadito:{0:.4f}\nMap:{1:.4f}”
打印(msg.format(duration\u readinto、duration\u mmap、i\u part*批处理大小//兆字节))
批处理大小。追加(批处理大小*i部分//兆字节)
加载\u durations.append((duration\u readinto,duration\u mmap))
负载持续时间=np.asarray(负载持续时间)
plt.绘图(批次尺寸、装载持续时间)
plt.show()
情节如下:


我无法理解mmap是如何完全丢失的,即使是从1GB文件加载10MB的小批量数据。

对于这种顺序读取工作负载,通过系统调用readinto在很大程度上可以从操作系统预取中获益,而您可能必须为mmap设置MAP_POPULATE才能享受同样的好处。如果您测试随机读取工作负载,您将看到完全不同的比较。

mmap
是Linux中最昂贵的系统调用之一,在访问下一页时出现页面错误也会增加伤害。尝试使用
MAP\u POPULATE
。也可以尝试使用大型页面和更大的块。这可能会有点帮助。请注意,并行执行页面错误(页面清理)通常更快(至少在Linux上是如此)。感谢您的提示。Python mmap模块似乎没有显式包含该标志,但具有“”。我将尝试找出是否有任何标志与MAP_POPULATE匹配。