测试代码:
#ifdef _MSC_VER #include <sys/stat.h> #include <io.h> #include <Windows.h> #else #include <unistd.h> #endif #include <fcntl.h> #include <ctime> #include <cstdio> #include <cstdlib> #include <fstream> #ifdef _MSC_VER #define OPEN(fd, file) \ fd = _open(file, O_CREAT | O_RDWR | O_APPEND, S_IWRITE | S_IREAD) #define WRITE(fd, data, len) \ _write(fd, pszData, iDataLen) #define FLUSH(fd) \ _commit(fd) #define CLOSE(fd) \ _close(fd) #define SLEEP(s) \ Sleep(1000 * s) #else #define OPEN(fd, file) \ umask(002); \ fd = open(file, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP) #define WRITE(fd, data, len) \ write(fd, pszData, iDataLen); #define FLUSH(fd) \ fsync(fd) #define CLOSE(fd) \ close(fd) #define SLEEP(s) \ sleep(s) #endif static int s_iFd = -1; static FILE * s_pFile = NULL; static std::ofstream s_ofs; enum TEST_TYPE { TYPE_MIN, TYPE_HANDLE = TYPE_MIN, TYPE_FILE, TYPE_OFSTREAM, TYPE_MAX }; const char * GetType(enum TEST_TYPE enType) { switch (enType) { case TYPE_HANDLE: { return("handle"); } case TYPE_FILE: { return("FILE"); } case TYPE_OFSTREAM: { return("ofstream"); } default: { return("unknown"); } } }; void OpenFile(enum TEST_TYPE enType) { switch (enType) { case TYPE_HANDLE: { OPEN(s_iFd, "a.txt"); if (s_iFd < 0) { fprintf(stderr, "open failed\n"); exit(1); } break; } case TYPE_FILE: { s_pFile = fopen("b.txt", "w+"); if (NULL == s_pFile) { fprintf(stderr, "fopen failed\n"); exit(2); } break; } case TYPE_OFSTREAM: { s_ofs.open("c.txt", std::ios::binary | std::ios::app); if (!s_ofs) { fprintf(stderr, "ofstream::open failed\n"); exit(3); } break; } default: { fprintf(stderr, "open: unknown type\n"); exit(4); break; } } } void WriteFile(enum TEST_TYPE enType, const char * pszData, int iDataLen) { if (NULL == pszData || 0 >= iDataLen) { return; } switch (enType) { case TYPE_HANDLE: { while (0 < iDataLen) { int iWirteLen = WRITE(s_iFd, pszData, iDataLen); if (0 > iWirteLen) { fprintf(stderr, "write failed\n"); break; } pszData += iWirteLen; iDataLen -= iWirteLen; } FLUSH(s_iFd); break; } case TYPE_FILE: { while (0 < iDataLen) { int iWirteLen = fwrite(pszData, 1, iDataLen, s_pFile); if (0 > iWirteLen) { fprintf(stderr, "fwrite failed\n"); break; } pszData += iWirteLen; iDataLen -= iWirteLen; } fflush(s_pFile); break; } case TYPE_OFSTREAM: { s_ofs.write(pszData, iDataLen); if (s_ofs.fail()) { fprintf(stderr, "ofstream::write failed\n"); s_ofs.clear(); } s_ofs.flush(); break; } default: { fprintf(stderr, "write: unknown type\n"); exit(5); break; } } } void CloseFile(enum TEST_TYPE enType) { switch (enType) { case TYPE_HANDLE: { CLOSE(s_iFd); break; } case TYPE_FILE: { fclose(s_pFile); break; } case TYPE_OFSTREAM: { s_ofs.close(); break; } default: { fprintf(stderr, "close: unknown type\n"); exit(6); break; } } } int main(int argc, char * argv[]) { const char szData[] = "1234567890123456789012345678901234567890123456789012345678901234567890"; const int iDataLen = sizeof(szData) - 1; enum TEST_TYPE enIndex = TYPE_MIN; while (TYPE_MAX > enIndex) { const char * pszType = GetType(enIndex); OpenFile(enIndex); int iWriteCount = 0; int iPrintCount = 0; time_t tStartTime = time(NULL); time_t tLastTime = tStartTime; while (10 > iPrintCount) { WriteFile(enIndex, szData, iDataLen); ++iWriteCount; if (time(NULL) > tLastTime) { ++iPrintCount; tLastTime = time(NULL); fprintf(stdout, "type: %9s, speed: %9d\n", pszType, (iWriteCount / (tLastTime - tStartTime))); } } CloseFile(enIndex); enIndex = static_cast<enum TEST_TYPE>(enIndex + 1); SLEEP(2); }; return(0); }
测试结果:
Linux + no_flush: handle慢一个数量级, FILE与ofstream同一数量级, 但FILE略快 type: handle, speed: 365147 type: handle, speed: 553700 type: handle, speed: 620208 type: handle, speed: 660457 type: handle, speed: 683569 type: handle, speed: 698560 type: handle, speed: 710284 type: handle, speed: 718802 type: handle, speed: 726606 type: handle, speed: 729462 type: FILE, speed: 4557587 type: FILE, speed: 4805500 type: FILE, speed: 4266081 type: FILE, speed: 4493705 type: FILE, speed: 4859939 type: FILE, speed: 5003800 type: FILE, speed: 5072787 type: FILE, speed: 5132573 type: FILE, speed: 4857114 type: FILE, speed: 4878231 type: ofstream, speed: 3706144 type: ofstream, speed: 4089290 type: ofstream, speed: 4019945 type: ofstream, speed: 3723549 type: ofstream, speed: 3517367 type: ofstream, speed: 3674459 type: ofstream, speed: 3925795 type: ofstream, speed: 4079569 type: ofstream, speed: 3827552 type: ofstream, speed: 3762736 Linux + flush: handle慢四个数量级, FILE与ofstream同一数量级, 但FILE略快 type: handle, speed: 19 type: handle, speed: 29 type: handle, speed: 37 type: handle, speed: 37 type: handle, speed: 36 type: handle, speed: 36 type: handle, speed: 36 type: handle, speed: 37 type: handle, speed: 36 type: handle, speed: 38 type: FILE, speed: 627707 type: FILE, speed: 660472 type: FILE, speed: 670974 type: FILE, speed: 678343 type: FILE, speed: 683366 type: FILE, speed: 687264 type: FILE, speed: 690667 type: FILE, speed: 691783 type: FILE, speed: 692458 type: FILE, speed: 693900 type: ofstream, speed: 623825 type: ofstream, speed: 641605 type: ofstream, speed: 657575 type: ofstream, speed: 653685 type: ofstream, speed: 663389 type: ofstream, speed: 667315 type: ofstream, speed: 668244 type: ofstream, speed: 623023 type: ofstream, speed: 624355 type: ofstream, speed: 630020 Windows + no_flush: 三种方式, 速度都在同一个数量级, handle慢一些, 另外两个各有快慢; type: handle, speed: 71736 type: handle, speed: 91307 type: handle, speed: 99067 type: handle, speed: 102946 type: handle, speed: 105018 type: handle, speed: 106260 type: handle, speed: 107252 type: handle, speed: 108264 type: handle, speed: 108958 type: handle, speed: 109396 type: FILE, speed: 500532 type: FILE, speed: 334409 type: FILE, speed: 246716 type: FILE, speed: 228381 type: FILE, speed: 219697 type: FILE, speed: 213099 type: FILE, speed: 212147 type: FILE, speed: 209722 type: FILE, speed: 205950 type: FILE, speed: 205227 type: ofstream, speed: 435828 type: ofstream, speed: 313958 type: ofstream, speed: 297525 type: ofstream, speed: 274231 type: ofstream, speed: 296749 type: ofstream, speed: 312720 type: ofstream, speed: 330095 type: ofstream, speed: 332609 type: ofstream, speed: 322173 type: ofstream, speed: 345480 Windows + flush: handle慢四个数量级, FILE比ofstream快一半 type: handle, speed: 22 type: handle, speed: 37 type: handle, speed: 42 type: handle, speed: 44 type: handle, speed: 44 type: handle, speed: 42 type: handle, speed: 41 type: handle, speed: 41 type: handle, speed: 40 type: handle, speed: 40 type: FILE, speed: 121989 type: FILE, speed: 125874 type: FILE, speed: 126775 type: FILE, speed: 127286 type: FILE, speed: 127311 type: FILE, speed: 127464 type: FILE, speed: 127694 type: FILE, speed: 127870 type: FILE, speed: 128062 type: FILE, speed: 127990 type: ofstream, speed: 81132 type: ofstream, speed: 80382 type: ofstream, speed: 80439 type: ofstream, speed: 80652 type: ofstream, speed: 80746 type: ofstream, speed: 80823 type: ofstream, speed: 80845 type: ofstream, speed: 80889 type: ofstream, speed: 80810 type: ofstream, speed: 80738
自己总结下: FILE比ofstream略快, 比handle快很多, 但是handle是无二次缓冲的IO, 文件刷入更及时
摘自我发的帖子:
write+commit与ofstream的比较