I have tried all sorts of different combinations of flags such as FILE_FLAG_NO_BUFFERING and FILE_FLAG_OVERLAPPED, but fstream::write
still beats the Windows API version.
Does std::fstream
use internal buffering or other tricks or am I just messing up something?
#include <Windows.h>
#include <chrono>
#include <fstream>
#include <iostream>
std::string createTempFileName()
{
char buf[800];
tmpnam_s(buf, sizeof(buf));
return buf;
}
using namespace std::chrono;
int main()
{
std::uint64_t count = 1 << 23;
std::cout << "test fstream\n";
{
auto start = steady_clock::now();
auto path = createTempFileName();
std::fstream fs(path, std::ios_base::out | std::ios_base::in | std::ios_base::trunc | std::ios_base::binary);
for (std::uint64_t i = 0; i < count; i++)
fs.write((char*)&i, sizeof(i));
fs.close();
DeleteFile(path.c_str());
auto end = steady_clock::now();
std::cout << "fstream: Elapsed time in milliseconds : " << duration_cast<milliseconds>(end - start).count() << " ms\n";
}
std::cout << "test WriteFile\n";
{
auto start = steady_clock::now();
auto path = createTempFileName();
HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL);
for (std::uint64_t i = 0; i < count; i++)
WriteFile(file, &i, sizeof(i), NULL, NULL);
CloseHandle(file);
DeleteFile(path.c_str());
auto end = steady_clock::now();
std::cout << "WriteFile: Elapsed time in milliseconds : " << duration_cast<milliseconds>(end - start).count() << " ms\n";
}
}