gpt4 book ai didi

c# - FileStream.BeginWrite 优于 FileStream.Write?

转载 作者:太空狗 更新时间:2023-10-29 20:49:33 29 4
gpt4 key购买 nike

我需要对同一文件进行一批写入,但在文件内的不同位置。我想以尽可能最好的性能实现这一目标,因此查看了同步 FileStream.Write 和异步 FileStream.BeginWrite 方法。

同步实现很简单,只需在循环中调用 FileStream.Write 所需的次数。异步版本在循环中调用 FileStream.BeginWrite,然后执行 WaitHandle.WaitAll 以阻塞直到它们全部完成。令我惊讶的是,这比简单的同步版本慢。

我使用正确的构造函数创建了 FileStream,因此我可以请求异步操作,我还测试了 IAsyncResult.CompletedSynchronous 属性,该属性指示 False,因此它们确实以异步方式运行。似乎使用 BeginWrite 的唯一好处是您不会在写入发生时阻塞您的线程。除了这个好处之外,使用异步版本还有什么意义吗?

这是我用来玩异步方法的测试代码,也许有一个明显的错误?

        // Size of a chunk to be written to file
var chunk = 1024 * 64;

// Number of chunks to write async
var reps = 32;

// Create new file and set length
var fs = new FileStream(@"C:\testfile.dat",
FileMode.Create, FileAccess.ReadWrite,
FileShare.None, chunk, true);
fs.SetLength(chunk * reps);

// Allocate resources
byte[] bytes = new byte[chunk];
WaitHandle[] handles = new WaitHandle[reps];

for (int i = 0; i < reps; i++)
{
fs.Seek(chunk * i, SeekOrigin.Begin);
handles[i] = fs.BeginWrite(bytes, 0, chunk, null, null).AsyncWaitHandle;
}

// Wait for all async operations to complete
WaitHandle.WaitAll(handles);

fs.Flush();
fs.Close();

最佳答案

文件写入在 Windows 中得到了高度优化。您实际上并没有写入磁盘,而是写入了文件系统缓存。内存到内存的复制,以每秒 5 GB 或更高的速度运行。然后数据从缓存中延迟写入磁盘。进而优化以最小化写入磁头移动的次数。

这几乎不可能通过异步写入进行优化。这确实需要更长的时间,捕获线程池线程来进行回调并不是免费的。 async 的好处是最小化主线程延迟,而不是真正提高效率。只有当您写入大量数据时,您才会真正受益。超过将适合缓存。到那时,写入性能将从 5 GB/秒急剧下降到低于 ~50 MB/秒,因为缓存空间只能以磁盘写入的速率可用。

很难预测这种情况发生的确切时间。这取决于机器有多少 RAM 以及其他进程需要多少 RAM。当您写入 1 GB 或更少时,您基本上不用担心它。重要的是,当异步写入挂起时,您实际上有一些有用的事情要做。等待他们完成会失去使用它的意义。

关于c# - FileStream.BeginWrite 优于 FileStream.Write?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7733619/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com