通常我们读写文件时,都是用系统提供的write和read函数,但是我们都知道文件IO函数操作文件流效率要低于mmap,因为mmap相对write/read省去将数据拷贝到用户态的操作。那么他们之间的差距有多大呢,我们来用事实说话。
我们做这个测试之前,需要准备一个足够大的文件来进行对比,那么在linux下,系统为我们准备了现成的方法去创建一个大文件。主要有三种方法:
先贴上用mmap拷贝文件的方法,如果对mmap不熟悉的可以参考我上一篇总结的文章mmap ---- 内存映射原理。直接上代码:
1 #include<stdio.h> 2 #include<sys/mman.h> 3 #include<unistd.h> 4 #include<sys/types.h> 5 #include<stdlib.h> 6 #include<fcntl.h> 7 #include<sys/stat.h> 8 #include<string.h> 9 10 void mmapcopy(int sfd, size_t slen, int dfd) { 11 void *sptr = mmap(NULL, slen, PROT_READ, MAP_SHARED, sfd, 0); 12 void *dptr = mmap(NULL, slen, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); 13 if(dptr == MAP_FAILED) { 14 printf("mmap failed."); 15 return; 16 } 17 18 memcpy(dptr, sptr, slen); 19 20 munmap(sptr, slen); 21 munmap(dptr, slen); 22 } 23 24 int main(int argc, char* argv[]) { 25 if(argc != 3) { 26 printf("Usage: %s <src filename> <des filename>", argv[0]); 27 return -1; 28 } 29 30 int sfd; 31 int dfd; 32 33 if((sfd = open(argv[1], O_RDONLY)) < 0) { 34 printf("open src file failed."); 35 return sfd; 36 } 37 38 if((dfd = open(argv[2], O_CREAT | O_RDWR, 0664)) < 0) { 39 printf("create dst file failed."); 40 return dfd; 41 } 42 43 struct stat fst; 44 fstat(sfd, &fst); 45 truncate(argv[2], fst.st_size); 46 mmapcopy(sfd, fst.st_size, dfd); 47 48 close(sfd); 49 close(dfd); 50 51 return 0; 52 }分别测试了500M,1G和2G的文件拷贝,更大的没试,按照上面的规律来看,mmap似乎都是会快一点的,理论和实际都已经证明了,mmap进行文件拷贝的时候,是比较快的,因为它毕竟省去了copy_to_usr这一次拷贝。