zero-copy

在许多web应用中需要从磁盘中读取数据然后再将数据发送到socket中,而数据复制这一操作是非常消耗资源的。 当执行content_to_write = content[1024:]时,这个操作是复制从1024字节后的所有数据到变量content_to_write中,这个过程中增加了9.789MB内存。 有没有方法可以在这种操作中不复制数据呢,在实现了buffer protocol的对象中是可以实现的。当一个对象实现了这个协议,你可以使用memoryview构造一个memoryview对象,实现对源对象内存数据的引用。 使用memoryview 并没有产生多余的内存。 在web应用中将数据从磁盘复制,然后发送到socket中。 普通的复制操作是这样的

file.read(fileDesc, buf, len);
socket.send(socket, buf, len);

用户请求向web应用请求数据,数据复制的过程如下: 1.web应用调用系统调用read()方法,此处从用户态切换到内核态。1过程使用DMA从磁盘中复制数据到Read buffer中。 2.当read()返回时,此处从内核态切换到用户态,将数据复制到应用缓存中。 3.web应用调用send()方法,此处从用户态切换到内核态,将数据复制到内核空间的内存中。 4. 4过程使用DMA方法从内核空间的缓存中复制数据到socket中。 当数据量很大时,这一过程是极其缓慢的。


零拷贝方法:直接将数据从源端拷贝到目标端

os.sendfile(out, in, offset, count, [headers, ][trailers, ]flags=0) 

传统拷贝方法所消耗的时间: 零拷贝方法所消耗的时间: 使用传统方法的客户端: 使用零拷贝方法的客户端:没产生大内存

pip3 install memory_profiler
pip3 install line_profiler

Ref:
1.Efficient data transfer through zero copy
2.high-performance-in-python-with-zero-copy-and-the-buffer-protocol/