【发布时间】:2019-04-01 15:57:34
【问题描述】:
对于网络相关的框架,我需要大量的byte[] 缓冲区来读取和写入数据。创建新字节数组时,CLR 将使用0 初始化所有值。对于与流一起使用的缓冲区,这似乎是不必要的开销:
var buffer = new byte[65536];
var read = await stream.ReadAsync(buffer, 0, buffer.Length);
有没有办法在 C# 中创建 byte[] 数组而不用 0 初始化所有值?可能通过调用malloc 样式方法?我确定这个问题已经得到解答,但我没有找到任何线索。
【问题讨论】:
-
不,没有。您可以做的是使用 pool 缓冲区,因此开销只发生一次。然后,您需要确保您的逻辑处理数组中可能包含“旧”数据的事实。
-
虽然重用数组是一个好的开始,但我怀疑您可能还想研究“管道”,它可以为您提供
ArrayPool<byte>的所有优点,而且还有更多,包括更好的消费模型,以及使用非连续缓冲区的能力;管道是支撑令人印象深刻的 Kestrel 性能的 API。你说“网络相关框架”——在这种情况下,Pipelines.Sockets.Unofficial (nuget) 有一个 SocketPipe 桥用于直接消费,如果你需要中介,还有一个 StreamPipe 桥(例如,@987654328 @) -
@MarcGravell:非常感谢!尤其是 API 的
PositionOf和Advance在标记化/解析请求时似乎是梦想。在实现 HTTP/2 时,我将看看管道。 -
@Gene 注意:HTTP/2(客户端和服务器)作为 .NET Core 3 的一部分被添加;如果您想了解更多使用管道的详细信息/示例,我已经在博客中广泛介绍了它
-
@MarcGravell:嗯,这个项目的想法是自己实现 HTTP 协议,主要是出于教育原因。但我肯定会看看那里的接口。要达到每秒 700 万个请求,还有很长的路要走 :)
标签: c# .net streaming clr .net-standard