Re: fstream "write" faster than Windows "WriteFile"
"Alexander Grigoriev" <alegr@earthlink.net> wrote in message
news:%23ecO1uY6HHA.536@TK2MSFTNGP06.phx.gbl...
ofstream does internal buffering behind the curtain.
WriteFile requires a transition to kernel mode per each call.
If you write small pieces of data, WriteFile overhead can be bigger. Use
at least 4 KB buffer.
Yes, but there's only one call, well in the MB range.
<stefan.kniep@gmx.de> wrote in message
news:1188307981.764155.283840@57g2000hsv.googlegroups.com...
Hello,
On my system, sequentially writing 40 MB to disk with fstream "write"
is up to 3 times faster than doing the same using the "WriteFile"
function. I need to use the Windows API for file operations because I
have to handle files that are larger than 4GB. I tested the
"FILE_FLAG..." flags, but they make little difference when writing
files. The write performance is quite crucial in my application, so I
would like to know if there's a solution for this problem. Below is a
small test program that demonstrates the performance difference.
I am using Visual C++ 2005 Express along with the Platform SDK on
Windows XP SP2.
TIA, Stefan
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <conio.h>
#include <ctime>
using namespace std;
int main() {
clock_t tic;
int numPts = 10000000;
int numRuns = 5;
float* testPts = new float[numPts];
// open first file for output
ofstream fileOut1("e:/test1", ios::binary | ios::trunc);
if (!fileOut1.is_open()) {
cout<<"error opening file"<<endl;
}
// open second file for output
HANDLE fileOut2 = CreateFile(L"e:/test2", GENERIC_WRITE, NULL, NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fileOut2 == INVALID_HANDLE_VALUE) {
cout<<"error opening file"<<endl;
}
// repeat the test "numRuns" times
for (int i=0; i<numRuns; i++) {
//write to first file
cout<<"writing to first file..."<<flush;
fileOut1.seekp(0, ios::beg);
tic = clock();
fileOut1.write((char*)testPts, numPts*sizeof(float));
if (!fileOut1.good()) {
cout<<"error writing to file"<<endl;
}
else {
cout<<"ellapsed time: "<<((double)(std::clock()-tic))/
CLOCKS_PER_SEC<<" seconds"<<endl;
}
//write to second file
cout<<"writing to second file..."<<flush;
DWORD numBytesWritten;
SetFilePointer(fileOut2, 0, NULL, FILE_BEGIN);
tic = clock();
if(!WriteFile(fileOut2, (char*)testPts, numPts*sizeof(float),
&numBytesWritten, NULL)
|| numBytesWritten != numPts*sizeof(float))
{
cout<<"error writing to file"<<endl;
}
else {
cout<<"ellapsed time: "<<((double)(std::clock()-tic))/
CLOCKS_PER_SEC<<" seconds\n"<<endl;
}
}
fileOut1.close();
CloseHandle(fileOut2);
delete[] testPts;
cout<<"(press any key to continue)"<<flush;
_getch();
}