我正在尝试扫描一个包含1000个1.4 GB文件的文件夹,有时在很多计算机上需要10分钟,这是非常不可接受的。 我在下面对此编码,我想知道如果可能的话我可以加快速度。 请注意,文件永远不会超过250MB,因此缓冲区。 此代码针对文件夹中的每个文件运行。
HANDLE hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize != -1)
{
if (dwSize > 0)
{
DWORD dwChecksum = 0;
DWORD dwReadS = 0;
DWORD dwReadFar = 0;
bool bFailed = false;
if (ReadFile(hFile, pFileBuffer, 250000000, &dwReadS, NULL))
{
dwChecksum = CalculateChksum(pFileBuffer, dwReadS);
}
else
{
bFailed = true;
}
}
}
}
DWORD CalculateChksum(BYTE* pData, int len, DWORD CRC)
{
DWORD crc = CRC;
const DWORD* current = (const DWORD*)pData;
while (len >= 4)
{
crc = *current++ + crc;
len -= 4;
}
const BYTE* currentChar = (const BYTE*)current;
while (len-- > 0)
crc = *currentChar++ + crc;
return crc;
}
答案 0 :(得分:1)
部分读取文件时,CPU处于空闲状态。为了加快速度,请读取1 MB块并动态解码。将FILE_FLAG_SEQUENTIAL_SCAN
传递给CreateFile
,以便Windows知道预取下一个块。
此外,请确保使用优化版本进行测试。您的功能非常简单,单个线程应该跟上磁盘I / O,但在调试版本中可能不是这种情况。
顺便说一句,你知道那不是CRC吗?您的算法无法捕获诸如字节序交换之类的简单修改。答案 1 :(得分:0)
预先获取整个文件列表并创建一个列表。创建一个说20个线程的池。让每个线程获取下一个未处理的文件,处理它并更新CRC。这应该会给你一个很大的加速。
对于类似的问题,我看到了巨大的改进。我曾经要求打开50K文件,然后计算一些与ACL相关的内容。在SSD上有20个线程,我可以将其降低到30秒。最初的单线程模式需要3分钟。