为什么使用Python mmap模块比从C+;调用POSIX mmap慢得多+;?

为什么使用Python mmap模块比从C+;调用POSIX mmap慢得多+;?,python,c++,performance,posix,mmap,Python,C++,Performance,Posix,Mmap,C++代码: #包括 #包括 #包括 #包括 #包括 使用名称空间std; #定义文件模式(S|u IRUSR | S|u IWUSR | S|u IRGRP | S|IROTH) int main(){ 时间值tv1、tv2、tv3、tve; gettimeofday(&tv1,0); int size=0x1000000; int fd=打开(“数据”,O|RDWR | O|CREAT | O|TRUNC,文件模式); ftruncate(fd,尺寸); char*data=(char*)m

C++代码:

#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#定义文件模式(S|u IRUSR | S|u IWUSR | S|u IRGRP | S|IROTH)
int main(){
时间值tv1、tv2、tv3、tve;
gettimeofday(&tv1,0);
int size=0x1000000;
int fd=打开(“数据”,O|RDWR | O|CREAT | O|TRUNC,文件模式);
ftruncate(fd,尺寸);
char*data=(char*)mmap(0,大小,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
对于(int i=0;i
Python代码:

导入mmap
导入时间
t1=时间。时间()
大小=0x1000000
f=打开('数据/数据','w+'))
f、 截断(大小)
f、 关闭()
文件=打开('data/data','r+b')
buffer=mmap.mmap(file.fileno(),0)
对于X范围内的i(尺寸):
缓冲区[i]=“S”
buffer.close()
file.close()文件
t2=时间。时间()
打印“经过的时间:%.3fs%”(t2-t1)

我认为这两个程序本质上是相同的,因为C++和Python调用同一个系统调用(<代码> MMAP)。 但是Python版本比C++慢得多:

Python: Time elapsed: 1.981s
C++:    Time elapsed: 0.062143s

<强>可以解释一下MMAP Python比C++慢得多吗?< /强>


环境:

C++:

Python:

$ python --version
Python 2.7.11 :: Anaconda 4.0.0 (x86_64)

不是
mmap
更慢,而是用值填充数组。众所周知,Python在执行基本操作时速度较慢。使用更高级别的操作:

buffer[:] = 'S' * size

详述丹尼尔所说的任何一个Python操作都有更多的开销(在某些情况下,数量比数量级要多),比在C++中实现一个解决方案的代码量要多。 填充缓冲区的循环确实是罪魁祸首,

mmap
模块本身要做的事情比您想象的要多得多,尽管它提供了一个语义与POSIX
mmap()
非常接近的接口。你知道POSIX
mmap()
是如何抛出一个
void*
(你只需要在某个时候使用
munmap()
来清理它)?Python的
mmap
必须分配一个
PyObject
结构来监视
void*
——通过向运行时提供元数据和回调、传播和排队读写、维护GIL状态、无论发生什么错误都清理其分配,使其符合Python的缓冲协议

所有这些都需要时间和记忆。我个人从未使用过
mmap
模块,因为它在任何I/O问题上都不会给您带来明显的优势,比如开箱即用–您可以轻松地使用
mmap
使事情变慢,也可以使事情变快


相反,我经常*确实*地发现,当从Python C/C++扩展中执行I/O时,使用POSIX
mmap()
非常有利(只要您注意GIL状态),这正是因为围绕
mmap()进行编码
一开始就避免了所有Python内部基础结构的东西。

对于xrange(size):x++
循环中的i,同一个程序的执行时间是多少非常有利您能否提供一个简单的用例示例?@Greg-sure:当需要随机访问文件内容时(以及比增量I/O性能更重要的时候),如在任意情况下。在幕后,Python2使用标准的C流(即文件*)和双缓冲区;Python3抛弃了那些基于简单描述符的I/O方案,并在Python中实现了缓冲和所有增量功能……这两种策略都为需要进行随机访问的算法(如图像处理或机器学习)带来了I/O瓶颈。
buffer[:] = 'S' * size