windows - 缓冲数据会提高 IStream 中的写入性能吗?
问题描述
我正在尝试从磁盘文件创建 IStream,然后将许多数据块写入其中。每个块的大小为 4096 字节。由于要写入的块很多,我只是想将几个块缓冲到一个大缓冲区中,当大缓冲区已满时,我将执行实际写入 IStream。这会提高写入性能吗?
我尝试制作一个小应用程序来测试:
CFile SrcFile;
LPSTREAM lpStreamFile = NULL;
BYTE lpBuf[4096];
BYTE lpLBuf[65536];
BYTE* lpCurBuf;
UINT uRead;
DWORD uStart, uStop;
uStart = ::GetTickCount();
if (SrcFile.Open(_T("D:\\1GB.dat"), CFile::modeRead | CFile::shareExclusive | CFile::typeBinary))
{
SrcFile.SeekToBegin();
::DeleteFile(_T("F:\\1GB.dat"));
if (SUCCEEDED(SHCreateStreamOnFileEx(_T("F:\\1GB.dat"), STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DIRECT,
FILE_ATTRIBUTE_NORMAL, TRUE, NULL, &lpStreamFile)) && (lpStreamFile != NULL))
{
lpCurBuf = lpLBuf;
while (TRUE)
{
uRead = SrcFile.Read(lpBuf, 4096);
if ((lpCurBuf + uRead) > (lpLBuf + 65536))
{
lpStreamFile->Write(lpLBuf, lpCurBuf - lpLBuf, NULL);
lpCurBuf = lpLBuf;
}
::memcpy(lpCurBuf, lpBuf, uRead);
lpCurBuf += uRead;
// lpStreamFile->Write(lpBuf, 4096, NULL);
if (uRead < 4096)
break;
}
if (lpCurBuf > lpLBuf)
{
lpStreamFile->Write(lpLBuf, lpCurBuf - lpLBuf, NULL);
}
lpStreamFile->Commit(STGC_DEFAULT);
if (lpStreamFile != NULL)
{
// Release the stream
lpStreamFile->Release();
lpStreamFile = NULL;
}
}
SrcFile.Close();
}
uStop = GetTickCount();
CString strMsg;
strMsg.Format(_T("Total tick count = %u."), uStop - uStart);
AfxMessageBox(strMsg);
大缓冲区大小65536,是4096的16倍。我用一个1GB的数据文件做测试。
令我惊讶的是,当不使用大缓冲区时,总时间总是大约 10 秒。
但是,当使用大缓冲区时,第一次运行需要 30 秒,然后剩余的运行需要 10 秒。
所以看起来 IStream 已经有一个内部写入缓冲区,所以我的大缓冲区对它没有任何好处。但是,我找不到任何这样说的文件。我也找不到任何文档告诉我如何控制,例如设置缓冲区的大小。
解决方案
推荐阅读
- authentication - 如何在 RASA 中并行管理多个频道的唯一 user_id?
- ansible - 为什么复制似乎需要永远
- javascript - 在 sapper 中在 Polka 中创建单独的后端 API 或使用相同的 Polka server.js
- python - Python中的计划函数未启动
- php - Laravel 7 迁移:语法错误或访问冲突:1068 定义了多个主键
- javascript - 如何比较由不同格式的日期字符串生成的 Javascript 日期对象?
- javascript - 如何让 elevateZoom 与两个 div 一起工作
- express - 我无法删除 monngoose 和 expressjs 中的活动集合
- visual-studio-code - Visual Studio 代码编辑器无法自动完成、颜色编码或提供建议
- php - 在 000webhost 上工作的 heroku 错误