Pipelines 比 NetworkStream 快的根本原因是零拷贝内存访问和无状态机同步模型,减少 GC 压力 30%~60%、CPU 时间 20%~40%,尤其适合小包高频复用场景。

System.IO.Pipelines 为什么比 NetworkStream 快
根本原因不在“管道”本身,而在内存管理和同步模型。NetworkStream 默认走 Stream.ReadAsync / WriteAsync,每次调用都触发一次 Memory → ArraySegment → 内部缓冲区拷贝,还常伴随 Task 分配和状态机开销。Pipelines 的 PipeReader 直接暴露 ReadOnlySequence,数据零拷贝进入用户逻辑;PipeWriter 的 Advance 也只移动指针,不搬运字节。
典型场景下(如 HTTP 解析、Protobuf 反序列化),Pipelines 能减少 30%~60% 的 GC 压力和 20%~40% 的 CPU 时间 —— 尤其在小包高频通信时更明显。
NetworkStream 什么时候反而更简单可靠
不是所有场景都值得为性能上 Pipelines。如果你只是做一次性 TCP 连接、协议简单(比如发个 JSON 请求拿个响应)、吞吐量低于 1K QPS,NetworkStream 的代码量和调试成本显著更低。
-
NetworkStream天然支持Timeout属性(ReadTimeout/WriteTimeout),而 Pipelines 需手动结合CancellationToken+ValueTask状态判断 - 异常堆栈更直白:
IOException: Unable to read data from the transport connection比 Pipelines 中InvalidOperationException: Cannot await a completed result更容易定位网络中断 - 与
HttpClient、TcpClient.GetStream()无缝衔接,无额外适配层
真实压测中 Pipelines 的关键配置陷阱
没调好 PipeOptions,Pipelines 可能比 NetworkStream 还慢。常见误配:
- 默认
PipeOptions.PoolSize = 4096,但高并发下小 buffer 频繁分配会触发 GC —— 建议设为8192或更高(需权衡内存占用) -
MinimumSegmentSize设太小(如 512)会导致大量小段内存碎片;设太大(如 1MB)又浪费;推荐 4KB~16KB 区间,匹配多数网卡 MTU - 漏掉
UseSynchronizationContext = false,在 ASP.NET Core 默认同步上下文里会引发线程争用
正确初始化示例:
蓝科外贸网站管理系统中英文双语版v1.8是针对外贸中小企业而开发的具有简单易用、功能强大,性价比高、扩展性好,安全性高、稳定性好的系统,可以加快外贸企业网站开发的速度和减少开发的成本。让不同的用户在懂的少许html语言的基础上,就能够快速的构建一个风格个性化的而功能强大的中英文企业网站。
var options = new PipeOptions(
pool: ArrayPool.Create(8192, 1024),
minimumSegmentSize: 4096,
useSynchronizationContext: false);
var pipe = new Pipe(options);
从 NetworkStream 迁移到 Pipelines 的最小改动路径
不要重写整个通信层。优先替换接收侧,保留 NetworkStream 发送逻辑过渡:
- 用
TcpClient.GetStream()获取NetworkStream后,立即包装成StreamPipeReader:new StreamPipeReader(stream, options) - 发送仍用
stream.WriteAsync(...),等读侧稳定后再把写逻辑迁到PipeWriter - 注意:Pipelines 不自动处理粘包/半包,必须自己实现
SequenceReader边界判断 —— 别直接用reader.TryRead(out var result)就解析,要循环直到满足协议长度
粘包处理示意:
while (true)
{
var result = await reader.ReadAsync(ct);
var buffer = result.Buffer;
if (!buffer.IsEmpty)
{
var reader = new SequenceReader(buffer);
while (reader.TryReadLittleEndian(out int len) && reader.Remaining >= len)
{
// 解析 len 字节的有效载荷
reader.Advance(len);
}
reader.AdvanceTo(buffer.Start, buffer.End);
}
if (result.IsCompleted) break;
}
Pipelines 的性能优势只有在协议解析逻辑足够轻、且连接复用率高时才真正释放。单次短连接 + 复杂 JSON 序列化,NetworkStream 可能更省心。








