文件IO操作開發(fā)筆記(二):使用Cpp的ofstream對磁盤文件存儲進行性能測試以及測試工
前言
??在做到個別項目對日志要求較高,要求并行寫入的數據較多,盡管寫入數據的線程放在子線程,仍然會造成界面程序的假死(實際上Qt還是在跑,只是磁盤消耗超過瓶頸,造成假死(注意:控制臺還能看到打印輸出,linux則能看到打印輸出)。
??本篇升級了測試工具,并且測試了ofstream在USB3.0和M.2SSD上的寫入性能。
版本v1.1.0
??更新版本版本,新增了c++的ofstream寫入方式。
??

測試工具v1.1.0下載地址
??請自行溯源搜索,發(fā)不出
使用C++的ofstream測試結果
USB3.0移動硬盤測試結果
? ?

? ??

? ?所以,線程越開越多,在某一個閾值線程數(實際打開操作的文件數)會導致性能大幅下降,而且會持續(xù)有多個閾值類似的。
M.2主板上SSD測試結果
? ??

? ?

使用C++的ofstream(用flush)測試結果
USB3.0移動硬盤測試結果
? ??

? ??

M.2主板上SSD測試結果
??

??

??結論:這個明顯受到硬盤數據傳輸的影響。
關鍵代碼
void FileIoTestManager::slot_optFileUseCppOfstream(int loopTime, int loopWrite, int dataSize, bool flush){
? ?QDir dir;
? ?QString dirPath = QString("%1/%2")
? ? ? ? ? ? ? ? ? ? ? ? ? ?.arg(QApplication::applicationDirPath())
? ? ? ? ? ? ? ? ? ? ? ? ? ?.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh_mm_ss_zzz"));
? ?if(dir.mkpath(dirPath))
? ?{
? ? ? ?message(QString("創(chuàng)建文件夾成功: %1").arg(dirPath));
? ?}else{
? ? ? ?message(QString("創(chuàng)建文件夾失敗: %1").arg(dirPath));
? ?}
? ?// 生成數據
? ?message(QString("生成測試數據,數據長度: %1").arg(dataSize));
? ?QByteArray byteArray;
? ?byteArray.append(dataSize, 0xFF);
? ?message(QString("==========================測試開始=============================="));
? ?double totalTime = 0; ? ? ? ? ? // 總計時間
? ?double fileTotalTime = 0; ? ? ? // 操作單個文件總時間
? ?double writeFileTime = 0; ? ? ? // 單個文件單詞寫入時間
? ?totalTime = QDateTime::currentDateTime().toMSecsSinceEpoch() * 1.0f;
? ?for(int loopIndex = 0; loopIndex < loopTime; loopIndex++)
? ?{
? ? ? ?QString filePath = QString("%1/%2_%3")
? ? ? ? ? ? ? ?.arg(dirPath)
? ? ? ? ? ? ? ?.arg(QDateTime::currentDateTime().toString("hh_mm_ss_zzz"))
? ? ? ? ? ? ? ?.arg(loopIndex, 6, 10, QChar('0'));
? ? ? ?std::ofstream outFile;
? ? ? ?outFile.open(filePath.toUtf8().constData());
? ? ? ?writeFileTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
? ? ? ?for(int writeIndex = 0; writeIndex < loopWrite; writeIndex++)
? ? ? ?{// ? ? ? ? ? ?message(QString(" ?第%1次寫入文件,寫入長度%2字節(jié)").arg(writeIndex + 1).arg(dataSize));
? ? ? ? ? ?outFile << byteArray.constData();
? ? ? ? ? ?if(flush)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?outFile.flush();
? ? ? ? ? ?}
? ? ? ? ? ?if(_stop)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?outFile.close();
? ? ? ? ? ? ? ?message(QString("==========================測試手動停止==========================="));
? ? ? ? ? ? ? ?_stop = false;
? ? ? ? ? ? ? ?emit signal_finished();
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?writeFileTime = QDateTime::currentDateTime().toMSecsSinceEpoch() - writeFileTime;
? ? ? ?writeFileTime = writeFileTime / loopWrite;
? ? ? ?message(QString("每次寫入數據平均耗時(不包含打開關閉文件): %1ms").arg(writeFileTime));// ? ? ? ?message(QString(" 第%1次關閉文件").arg(loopIndex + 1));
? ? ? ?outFile.close();
? ?}
? ?message(QString("==========================測試結果=============================="));
? ?totalTime = QDateTime::currentDateTime().toMSecsSinceEpoch() - totalTime;
? ?fileTotalTime = totalTime * 1.0f / loopTime;
? ?message(QString("操作創(chuàng)建文件次數: %1, 單個文件循環(huán)寫入次數: %2, 每次寫入固定數據長度: %3, %4")
? ? ? ? ? ?.arg(loopTime)
? ? ? ? ? ?.arg(loopWrite)
? ? ? ? ? ?.arg(dataSize)
? ? ? ? ? ?.arg(flush ? "每次使用flush" : "不使用flush"));
? ?message(QString("總耗時: %1ms").arg(totalTime));
? ?message(QString("單個文件循環(huán)寫入平均總耗時(包括打開關閉文件): %1ms").arg(fileTotalTime));
? ?message(QString("每次寫入數據平均耗時(包括打開關閉文件: %1ms").arg(fileTotalTime * 1.0f / loopWrite));
? ?message(QString("==========================測試結束=============================="));
? ?emit signal_finished();
? ?return;}
工程模板v1.1.0
??

后續(xù)
??會持續(xù)補充測試其他方式,ofstream本次測試比QFile的性能還差一些。