原帖https://stackoverflow.com/questions/11563963/writing-a-binary-file-in-c-very-fast,笔者在此基础上将原来的option3替换为unistd.h中的write,因为原来option3和option1差不多,且测试结果没有什么区别。
方法1:fstream中到write
方法2:C中的fwrite
方法3:unistd.h中的write
#include <fstream>
#include <chrono>
#include <vector>
#include <cstdint>
#include <numeric>
#include <random>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <unistd.h>
#include <fcntl.h>
std::vector<uint64_t> data;
std::vector<uint64_t> GenerateData(std::size_t bytes)
{
assert(bytes % sizeof(uint64_t) == 0);
std::vector<uint64_t> data(bytes / sizeof(uint64_t));
std::iota(data.begin(), data.end(), 0);
std::shuffle(data.begin(), data.end(), std::mt19937{ std::random_device{}() });
return data;
}
long long option_1(std::size_t bytes)
{
auto startTime = std::chrono::high_resolution_clock::now();
auto myfile = std::fstream("file.binary", std::ios::out | std::ios::binary);
myfile.write((char*)&data[0], bytes);
myfile.close();
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
long long option_2(std::size_t bytes)
{
auto startTime = std::chrono::high_resolution_clock::now();
FILE* file = fopen("file.binary", "wb");
fwrite(&data[0], 1, bytes, file);
fclose(file);
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
long long option_3(std::size_t bytes)
{
auto startTime = std::chrono::high_resolution_clock::now();
int file_fd = open("file.binary", O_WRONLY | O_CREAT, 00666);
write(file_fd, &data[0], bytes);
close(file_fd);
auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}
int main(int argc, char * argv[])
{
if(argc < 2)
{
std::cout << "Need argv[1],like 100 (Unit:MB)" << std::endl;
return 0;
}
const std::size_t kB = 1024;
const std::size_t MB = 1024 * kB;
const std::size_t GB = 1024 * MB;
size_t size = atoi(argv[1]) *MB;
data = GenerateData(size);
std::cout << "Testing begin...." << std::endl;
std::cout << "option1, " << size / MB << "MB: " << option_1(size) << "ms" << std::endl;
std::cout << "option2, " << size / MB << "MB: " << option_2(size) << "ms" << std::endl;
std::cout << "option3, " << size / MB << "MB: " << option_3(size) << "ms" << std::endl;
unlink("file.binary");
return 0;
}
测试环境:Ubuntu 16.04
测试结果:
- $ ./Test_write_speed 50
Testing begin…
option1, 50MB: 129ms
option2, 50MB: 129ms
option3, 50MB: 98ms - $ ./Test_write_speed 100
Testing begin…
option1, 100MB: 249ms
option2, 100MB: 257ms
option3, 100MB: 196ms - $ ./Test_write_speed 300
Testing begin…
option1, 300MB: 731ms
option2, 300MB: 763ms
option3, 300MB: 583ms - $ ./Test_write_speed 500
Testing begin…
option1, 500MB: 1239ms
option2, 500MB: 1271ms
option3, 500MB: 968ms
结论:
unistd.h中的write最快