本文共 18144 字,大约阅读时间需要 60 分钟。
/****************************************************************
* 说明: 用不同的方法,测试写文件的速度,测试结果表明 * 改变COUNT的值,将改变写入文件的大小 * 测试CPU使用率方法: /usr/bin/time -f "CPU: %P" ./a.out 1 * ************************************************************/ #include <cstdio> #include <time.h> #include <iostream> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <sys/time.h>using namespace std;
#define WRITE_FILE /*定义这个宏,则把数据写到文件,否则不写,用于测试不写文件用的时间*/
const unsigned short usPageSize = 4*1024; /*4K*/
const unsigned long STR_LEN = (usPageSize*1024) +1; /*每次缓存4M有效数据写入文件 ,最后一个字节保证 null-terminated ,不写入文件*/ const unsigned long COUNT = 256; /*改变COUNT的值,将改变写入文件的大小 256 --->1G 16 ---> 64M 请问 为什么512 2G出现总线错误? */char g_strUserFlow[2048] ;
/****************************************************************
* 功能: 用fprintf,测试写文件速度 * ************************************************************/ void fprintf_write1();/****************************************************************
* 功能: 用fwrite,(使用系统缓存)测试写文件速度 * ************************************************************/ void fwrite_write2();/****************************************************************
* 功能: 用fwrite(自己分配4M缓存,每次写入4M, 然后fflush),测试写文件速度 * ************************************************************/ void fwrite_write2_1();/****************************************************************
* 功能: 用write, 设O_DIRECT,自己维护缓存, ,测试写文件速度 * ************************************************************/ void write_direct3();/****************************************************************
* 功能: 用write,(使用系统缓存),测试写文件速度 * ************************************************************/ void write_write4();/****************************************************************
* 功能: 用write,(自己分配4M缓存,每次写入4M, 每次fsync),测试写文件速度 * ************************************************************/ void write_write4_1();/****************************************************************
* 功能: 用mmap每次映射4M内存,测试写文件速度 * ************************************************************/ void mmap_write5();/****************************************************************
* 功能: 用mmap每次一次性映射全部文件,测试写文件速度 * ************************************************************/ void mmap_write5_1();/****************************************************************
* 功能: 用mmap每次映射1M内存,测试写文件速度 * ************************************************************/ void mmap_write5_2();/****************************************************************
* 功能: 用mmap每次映射2M内存,测试写文件速度 * ************************************************************/ void mmap_write5_3(); //void cout_write8();void setRecordData(char *pStrBuf, unsigned long ulBufSize, char *pStrLeftDataBuf, unsigned short &usDataBufSize);
int main(int argc, char *argv[])
{ int iFlowLen; int iNum = 1; if(2==argc && 0==strcmp("--help", argv[1])) { printf("\nusage:" "\n\t run all : ./a.out " "\n\t run fprintf_write1(): ./a.out 1" "\n\t run fwrite_write2(): ./a.out 2" "\n\t run fwrite_write2_1(): ./a.out 2.1" "\n\t run write_direct3(): ./a.out 3" "\n\t run write_write4(): ./a.out 4" "\n\t run write_write4_1(): ./a.out 4.1" "\n\t run mmap_write5(): ./a.out 5" "\n\t run mmap_write5_1(): ./a.out 5.1" "\n\t run mmap_write5_2(): ./a.out 5.2" "\n\t run mmap_write5_3(): ./a.out 5.3\n" ); exit(0); } if(3==argc) { iNum = atoi(argv[2]); } iFlowLen = sprintf(g_strUserFlow, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" "\t%s\t%s\t%s\t\n", "1319618698.0", "2011-10-26 16:44:58", "1319618697.0", "1319618698.0", "460030919115059", "00a000002266f525", "", "", "Q d 8613309117677", "59", "2", "0", "1", " -1", "G02", "S38", "-1", "-1", "0", "-1", "-1", "123", "115.168.25.12", "172.26.187.5", "366B0004", "366B0004413E", "10.173.8.248", "10.0.0.200", "6", "52042", "80", "102", "3000000", "14", "14", "-", "-", "1", "8", "7", "1362", "5230", "1362", "5230", "0", "0", "0", "0", "0", "s.image.wap.soso.com", "", "0", "0", " 0", " -", "-", "-", " -", "14", "14", "0", "wap1", "0", "-", " -", "-", "PDSN_02", "延安BSC2", "0", "0", "", "-1", "", "-1", "-1", "-1", "0", "-1", "1491300", "", "0", "a8:c000:6380:0:ac1a:ba04:8b00:0/1200:a8c0:63:8000:ac:1aba:48b:670","-");printf("filesize = %lu\n", COUNT*(STR_LEN-1));
#ifdef WRITE_FILE printf("define WRITE_FILE\n\n"); #else printf("not define WRITE_FILE\n\n"); #endifwhile(iNum--)
{ if(1==argc) { fprintf_write1(); fwrite_write2(); fwrite_write2_1(); write_direct3(); write_write4(); write_write4_1(); mmap_write5(); mmap_write5_1(); mmap_write5_2(); mmap_write5_3(); } else if(1 == atof(argv[1])) { fprintf_write1(); } else if(2 == atof(argv[1])) { fwrite_write2(); } else if(2.1 == atof(argv[1])) { fwrite_write2_1(); } else if(3 == atof(argv[1])) { write_direct3(); } else if(4 == atof(argv[1])) { write_write4(); } else if(4.1 == atof(argv[1])) { write_write4_1(); } else if(5 == atof(argv[1])) { mmap_write5(); } else if(5.1 == atof(argv[1])) { mmap_write5_1(); } else if(5.2 == atof(argv[1])) { mmap_write5_2(); } else if(5.3 == atof(argv[1])) { mmap_write5_3(); } }//cout_write8();
}double diffTime(struct timeval struStop, struct timeval struStart)
{ return ( (double)((1000000.0*struStop.tv_sec + struStop.tv_usec) - (1000000.0*struStart.tv_sec + struStart.tv_usec)) )/1000000.0; }void fprintf_write1()
{ int i = 0; FILE *fp = NULL; struct timeval struStart; struct timeval struStop; char strData[1024+1] = {0}; gettimeofday(&struStart, NULL); unsigned long ulStart = clock(); fp = fopen("data.txt", "w+"); char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData);for (i =0; i< COUNT*usPageSize ; i++)
{ setRecordData(strData, 1024+1, strLeftData, strSize); // 每次写1024 ,'\0' 不写入 #ifdef WRITE_FILE fprintf(fp, "%s", strData); #endif }fclose(fp);
printf("fprintf_write1:\t %.3lf (clock time)\n", double(clock()-ulStart)/CLOCKS_PER_SEC); gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void fwrite_write2()
{ int i = 0; FILE *fp = NULL; unsigned long ulStart; struct timeval struStart; struct timeval struStop; char strData[1024+1] = {0}; char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData); gettimeofday(&struStart, NULL); ulStart = clock(); fp = fopen("data.txt", "w+");for (i=0; i<COUNT*usPageSize; i++)
{ setRecordData(strData, 1024+1, strLeftData, strSize); #ifdef WRITE_FILE fwrite(strData, 1024, 1, fp); #endif }fclose(fp);
printf("fwrite_write2:\t %.3lf (clock time),using system buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC); gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); } void fwrite_write2_1() { //char *pTmp = NULL; int i; //int j; FILE *fp = NULL; unsigned long ulStart; struct timeval struStart; struct timeval struStop;char strData[STR_LEN] = {0}; //4M
char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData); gettimeofday(&struStart, NULL); ulStart = clock(); fp = fopen("data.txt", "w+");if (NULL == fp)
{ perror("Cannot open file : "); return; }for (i=0; i<COUNT; i++)
{ setRecordData(strData, STR_LEN , strLeftData, strSize); #ifdef WRITE_FILE fwrite(strData, STR_LEN-1, 1, fp); // 每次写入4M fflush(fp); #endif } fclose(fp);printf("fwrite_write2_1: %.3lf (clock time), allocate 4M, every time fflush()\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); return ; }void write_direct3()
{ //char strTmp[1024]; //char *pTmp = NULL; int i; int j; int fd = -1, ret = -10; unsigned long ulStart; struct timeval struStart; struct timeval struStop; //char strData[STR_LEN] = {0}; char *buf = NULL; char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData); //buf = (char *)valloc(1024*usPageSize); posix_memalign((void**)&buf, usPageSize, STR_LEN ); //typedef char _aligned_char __attribute__ ((aligned (8192))); //_aligned_char buf[1024*usPageSize]; gettimeofday(&struStart, NULL); ulStart = clock(); fd = open("data.txt", O_RDWR |O_CREAT|O_DIRECT, 00600);if (fd<0)
{ perror("Cannot open file : "); return; }for (i=0; i<COUNT; i++)
{ memset(buf, 0, 1024*usPageSize); setRecordData(buf, STR_LEN, strLeftData, strSize);#ifdef WRITE_FILE
write(fd, buf, STR_LEN-1); #endif }free(buf);
close(fd);printf("write_direct3:\t %.3lf (clock time),using O_DIRECT, allocate 4M\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); return ; }void write_write4()
{ int i = 0; int fd; unsigned long ulStart; struct timeval struStart; struct timeval struStop; char strData[1024+1] = {0}; char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData);gettimeofday(&struStart, NULL); ulStart = clock(); fd = open("data.txt", O_CREAT | O_RDWR);
for (i=0; i<COUNT*usPageSize; i++)
{ setRecordData(strData, 1024+1 , strLeftData, strSize); #ifdef WRITE_FILE write(fd, strData, 1024); #endif }close(fd);
printf("write_write4:\t %.3lf (clock time), using system buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC); gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void write_write4_1()
{ //char buf[1024*usPageSize]; //4M int i; int fd = -1, ret = -10; unsigned long ulStart; struct timeval struStart; struct timeval struStop; char strData[STR_LEN] = {0}; char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData); //memset(buf, 0, 1024*usPageSize);gettimeofday(&struStart, NULL); ulStart = clock(); fd = open("data.txt", O_RDWR |O_CREAT, 00600);
if (fd<0)
{ perror("Cannot open file : "); return; }for (i=0; i<COUNT; i++)
{ setRecordData(strData, STR_LEN , strLeftData, strSize); #ifdef WRITE_FILE write(fd, strData, STR_LEN-1); /*一次写4M*/ fsync(fd); #endif } close(fd);printf("write_write4_1:\t %.3lf (clock time), alloc 4M buffer, every time using fsync()\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); return ; }void mmap_write5()
{ int i = 0, j = 0; char *pMap = NULL; int iPagesize; int fd; unsigned long ulStart; struct timeval struStart; struct timeval struStop;char strData[STR_LEN] = {0};
char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData);//iPagesize = getpagesize();
gettimeofday(&struStart, NULL); ulStart = clock(); fd = open("data.txt",O_RDWR|O_CREAT,00600); ftruncate(fd, COUNT*(STR_LEN-1)); #ifndef WRITE_FILE pMap = (char *)calloc(1, STR_LEN-1); #endif for (i = 0; i < COUNT; i++) { #ifdef WRITE_FILE pMap = (char *)mmap(0,STR_LEN-1, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)); // 每次打开4M if(MAP_FAILED == pMap) { perror("mmap_write5 error mmap() :"); return; } //ftruncate(fd, i*(STR_LEN-1) + (STR_LEN-1) );#endif setRecordData(strData, STR_LEN , strLeftData, strSize); memcpy(pMap , strData, STR_LEN-1);
#ifdef WRITE_FILE
munmap(pMap, STR_LEN-1); #endif } close(fd); #ifndef WRITE_FILE free(pMap); #endifprintf("mmap_write5: %.3lf (clock time), mmap: 4M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void mmap_write5_1()
{ int i = 0, j = 0; char *pMap = NULL; int iPagesize; int fd; unsigned long ulStart; struct timeval struStart; struct timeval struStop;char strData[STR_LEN] = {0};
char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData);//iPagesize = getpagesize();
gettimeofday(&struStart, NULL); ulStart = clock();#ifndef WRITE_FILE
pMap = (char *)calloc(1, 1024*usPageSize*COUNT); if(NULL==pMap) { printf("pMap calloc error\n\n"); return; } #endif fd = open("data.txt",O_RDWR|O_CREAT,00600); #ifdef WRITE_FILE pMap = (char *)mmap(0,(STR_LEN-1)*COUNT, PROT_WRITE, MAP_SHARED, fd, 0); // 一次全部打开文件映射(内存要求) ftruncate(fd, (STR_LEN-1)*COUNT ); #endif for (j=0; j<COUNT; j++) { setRecordData(strData, STR_LEN , strLeftData, strSize); memcpy(pMap + j*(STR_LEN-1), strData, STR_LEN-1); } #ifdef WRITE_FILE munmap(pMap, (STR_LEN-1)*COUNT); #endif close(fd);#ifndef WRITE_FILE
free(pMap); #endifprintf("mmap_write5_1:\t %.3lf (clock time), mmap: all buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void mmap_write5_2()
{ int i = 0; char *pMap = NULL; int iPagesize; int fd; unsigned long ulStart; struct timeval struStart; struct timeval struStop;char strData[STR_LEN] = {0};
char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData);gettimeofday(&struStart, NULL);
ulStart = clock();#ifndef WRITE_FILE
pMap = (char *)calloc(1, (STR_LEN-1)/4); #endiffd = open("data.txt",O_RDWR|O_CREAT,00600);
ftruncate(fd, COUNT*(STR_LEN-1)); for (i = 0; i < 4*COUNT; i++) { #ifdef WRITE_FILE pMap = (char *)mmap(0,(STR_LEN-1)/4, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)/4); // 每次打开1M //ftruncate(fd, i*(STR_LEN-1)/4 + (STR_LEN-1)/4 ); #endif setRecordData(strData, (STR_LEN-1)/4 +1 , strLeftData, strSize); memcpy(pMap , strData, (STR_LEN-1)/4); #ifdef WRITE_FILE munmap(pMap, (STR_LEN-1)/4); #endif } close(fd); #ifndef WRITE_FILE free(pMap); #endifprintf("mmap_write5_2: %.3lf(clock time) (clock time), mmap: 1M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void mmap_write5_3()
{ int i = 0; char *pMap = NULL; int iPagesize; int fd; unsigned long ulStart; struct timeval struStart; struct timeval struStop;char strData[STR_LEN] = {0};
char strLeftData[2048] = {0}; unsigned short strSize = sizeof(strLeftData); gettimeofday(&struStart, NULL); ulStart = clock();#ifndef WRITE_FILE
pMap = (char *)calloc(1, 512*usPageSize); #endif fd = open("data.txt",O_RDWR|O_CREAT,00600); ftruncate(fd, COUNT*(STR_LEN-1)); for (i = 0; i < 2*COUNT; i++) { #ifdef WRITE_FILE pMap = (char *)mmap(0,(STR_LEN-1)/2, PROT_WRITE, MAP_SHARED, fd, i*(STR_LEN-1)/2); // 每次打开2M //ftruncate(fd, i*(STR_LEN-1)/2 + (STR_LEN-1)/2 ); #endif setRecordData(strData, (STR_LEN-1)/2 +1 , strLeftData, strSize); memcpy(pMap , strData, (STR_LEN-1)/2); #ifdef WRITE_FILE munmap(pMap, (STR_LEN-1)/2); #endif } close(fd);#ifndef WRITE_FILE
free(pMap); #endifprintf("mmap_write5_3: %.3lf (clock time), mmap: 2M buffer\n", double(clock()-ulStart)/CLOCKS_PER_SEC);
gettimeofday(&struStop, NULL); printf("all time diff: %.3lf\n\n", diffTime(struStop, struStart)); }void setRecordData(char *pStrBuf, unsigned long ulBufSize, char *pStrLeftDataBuf, unsigned short &usDataBufSize)
{ unsigned long ulLeftBufLen = ulBufSize; short sCopyLen = 0; unsigned short usLeftCharLen = 0; char *pStrBufTmp = pStrBuf; char *pStrTmp = pStrLeftDataBuf;if (NULL==pStrBuf || NULL==pStrLeftDataBuf)
{ return ; } sCopyLen = snprintf(pStrBufTmp, ulLeftBufLen, pStrTmp);if(sCopyLen<0)
{ perror("snprintf error: "); return ; }if( sCopyLen < ulLeftBufLen-1 )
{ ulLeftBufLen = ulLeftBufLen - sCopyLen; pStrBufTmp += sCopyLen; pStrTmp = g_strUserFlow;while(ulLeftBufLen > 0)
{ sCopyLen = snprintf(pStrBufTmp, ulLeftBufLen, pStrTmp); if(sCopyLen<0) { perror("snprintf error: "); return; } if( sCopyLen < ulLeftBufLen-1 ) { ulLeftBufLen = ulLeftBufLen - sCopyLen; pStrBufTmp += sCopyLen; } else { break; } } }/*剩下的拷到pStrLeftDataBuf*/
strncpy(pStrLeftDataBuf, pStrTmp + (ulLeftBufLen-1), usDataBufSize-1 ); /*确保:pStrLeftDataBuf[usDataBufSize-1] = '\0'*/ }
写文件速度测试:
函数写文件方法简介:
1,void fprintf_write1()
用fprintf函数写文件,测试写文件速度。
2,void fwrite_write2()
用fwrite函数写文件,使用系统缓存,测试写文件速度。
3,void fwrite_write2_1(),
用fwrite函数写文件,自己分配4M缓存,每次写入4M,然后调用fflush,测试写文件速度。
4,void write_direct3();
用write写文件,设0_DIRECT,自己维护4M的缓存,测试写文件速度。
5,void write_write4();
用write写文件,使用系统缓存,测试写文件速度。,
6,voidwrite_write4_1();
用write写文件,自己分配4M缓存,每次写入4M,然后调用fsync,测试写文件速度。,
7,voidmmap_write5();
用mmap每次映射4M内存,测试写文件速度。
8,void mmap_write5_1();
用mmap每次映射全部文件大小的内存,测试写文件速度。
9,voidmmap_write5_2();
用mmap每次映射1M内存,测试写文件速度。,
10, mmap_write5_3();
用mmap每次映射2M内存,测试写文件速度。
测试命令:/usr/bin/time -f "CPU: %P" ./a.out 1
测试结果:1,写入文件大小:1G
函数名 | Clock()差值 | 实际时间 | CPU使用率(%) |
fprintf_write1() avg(实际时间) = 16.255 | 9.160 8.870 8.090 | 15.329 17.706 15.729 | 59 49 51 |
fwrite_write2() avg(实际时间) = 18.676 | 10.860 8.320 9.050 | 18.775 20.639 16.615 | 57 40 53 |
fwrite_write2_1(), avg(实际时间) = 16.714 | 6.830 4.230 4.270 | 17.414 16.067 16.660 | 38 26 25 |
write_direct3(); avg(实际时间) = 19.290 | 2.130 2.050 1.920 | 19.897 18.707 19.266 | 10 10 9 |
write_write4(); avg(实际时间) =58.363 | 23.840 23.870 24.700 | 58.632 58.123 58.333 | 40 41 42 |
write_write4_1(); avg(实际时间) = 24.918 | 4.670 4.320 3.850 | 21.260 31.874 21.621 | 21 13 17 |
mmap_write5() avg(实际时间) = 16.794 | 5.230 5.750 5.760 | 16.672 16.019 17.692 | 31 35 32 |
mmap_write5_1() avg(实际时间) = 55.473 | 8.360 7.680 8.670 | 58.568 53.894 53.958 | 14 14 16 |
mmap_write5_2() avg(实际时间) =14.954 | 4.920 5.200 5.290 | 14.862 15.911 14.088 | 32 32 37 |
mmap_write5_3() avg(实际时间) =16.317 | 5.210 5.270 5.010 | 15.451 15.746 17.759 | 33 33 28 |
结果:mmap_write5_2()最快
2,写入文件大小:64M
函数名 | Clock()差值 | 实际执行时间 | CPU使用率(%) | |
fprintf_write1() avg(实际时间) =0.940 | 0.790 0.460 0.440 | 1.404 0.726 0.691 | 55 65 63 | |
fwrite_write2() avg(实际时间) =0.723 | 0.650 0.440 0.430 | 0.819 0.668 0.682 | 79 66 63 | |
fwrite_write2_1() avg(实际时间) =0.327 | 0.330 0.190 0.190 | 0.407 0.290 0.285 | 79 67 64 | |
write_direct3() avg(实际时间) =0.915 | 0.150 0.150’ 0.130 | 0.928 0.893 0.923 | 17 17 15 | |
write_write4() avg(实际时间) =0.773 | 0.610 0.500 0.510 | 0.889 0.711 0.718 | 69 70 71 | |
write_write4_1() avg(实际时间) =1.262 | 0.370 0.240 0.190 | 1.433 1.213 1.139 | 26 21 17 | |
mmap_write5() avg(实际时间) =0.315 | 0.330 0.180 0.180 | 0.406 0.268 0.271 | 81 64 65 | |
mmap_write5_1() avg(实际时间) =0.357 | 0.360 0.220 0.230 | 0.465 0.290 0.316 | 79 73 72 | |
mmap_write5_2() avg(实际时间) =0.287 | 0.200 0.190 0.180 | 0.289 0.292 0.282 | 65 65 61 | |
mmap_write5_3() avg(实际时间) =0.345 | 0.390 0.190 0.190 | 0.471 0.291 0.275 | 81 63 67 |
结果:mmap_write5_2()最快
总结: 用mmap每次映射1M内存,测试得到最快速度。
转载地址:http://otemi.baihongyu.com/