高性能缓冲区操作类库文档
本文档库包含了 NewLife.Core 中四个核心的高性能缓冲区操作类的详细说明和使用指南。
类库概述
类名 | 类型 | 主要用途 | 特点 |
|
| 高性能二进制数据读取 | 零分配读取、自动流扩展、支持多种数据类型 |
|
| 高性能二进制数据写入 | 零分配写入、固定缓冲区、支持多种数据类型 |
|
| Span操作辅助工具 | 编码转换、十六进制、边界搜索、数据修剪 |
|
| 池化动态缓冲区写入 | 基于数组池、动态扩容、IBufferWriter接口 |
核心设计理念
高性能优先
- 零分配操作:基于
Span<T>
和Memory<T>
的现代 .NET 内存模型
- 池化内存管理:使用
ArrayPool<T>
减少 GC 压力
- 直接内存访问:避免不必要的数据复制和转换
易用性设计
- 类型安全:泛型支持和强类型 API
- 一致性接口:遵循 .NET 标准约定
- 丰富的重载:支持多种使用场景
跨平台兼容
- 多框架支持:.NET Framework 4.5 到 .NET 9
- 条件编译优化:针对不同平台的特定优化
典型使用场景
网络协议处理
// 解析网络数据包
public void ProcessPacket(ReadOnlySpan<byte> packetData)
{
var reader = new SpanReader(packetData);
var header = reader.Read<PacketHeader>();
var messageId = reader.ReadEncodedInt();
var payload = reader.ReadBytes(header.PayloadLength);
ProcessMessage(messageId, payload);
}
// 构建响应数据包
public ReadOnlyMemory<byte> BuildResponse(int messageId, string content)
{
using var writer = new PooledByteBufferWriter(1024);
var spanWriter = new SpanWriter(writer.GetSpan());
spanWriter.Write(0x12345678); // Magic
spanWriter.WriteEncodedInt(messageId);
spanWriter.Write(content, 0); // 带长度前缀
writer.Advance(spanWriter.WrittenCount);
return writer.WrittenMemory;
}
二进制序列化
public byte[] SerializeObject<T>(T obj) where T : struct
{
using var writer = new PooledByteBufferWriter(1024);
var spanWriter = new SpanWriter(writer.GetSpan());
// 写入类型信息和版本
spanWriter.Write(typeof(T).Name, 0);
spanWriter.Write((short)1);
// 直接写入结构体
spanWriter.Write(obj);
writer.Advance(spanWriter.WrittenCount);
return writer.WrittenMemory.ToArray();
}
数据转换和格式化
public string FormatBinaryData(ReadOnlySpan<byte> data)
{
// 使用 SpanHelper 进行格式化
var hex = data.ToHex(" ", groupSize: 4, maxLength: 64);
var text = data.ToStr().Replace('\0', '.');
return $"Hex: {hex}\nText: {text}";
}
性能特点
内存分配对比
传统方式: 新方式:
┌─────────────────┐ ┌─────────────────┐
│ byte[] → string │ (GC) │ Span → string │ (GC减少)
│ MemoryStream │ (GC) │ PooledWriter │ (池化)
│ BinaryReader │ (GC) │ SpanReader │ (栈上)
│ StringBuilder │ (GC) │ SpanWriter │ (栈上)
└─────────────────┘ └─────────────────┘
性能基准(示例)
- SpanReader: 比
BinaryReader
快 2-3 倍,零额外分配
- SpanWriter: 比
BinaryWriter
快 2-4 倍,零额外分配
- PooledByteBufferWriter: 比
MemoryStream
减少 60-80% 的 GC 分配
- SpanHelper: 十六进制转换比
BitConverter.ToString
快 3-5 倍
使用注意事项
ref struct 限制
SpanReader
和 SpanWriter
是 ref struct
,有以下限制:
- 不能存储在堆上(类字段、装箱)
- 不能在异步方法中跨
await
使用
- 不能在 LINQ 查询中使用
- 不能作为泛型类型参数
生命周期管理
// ? 正确使用
void ProcessData(ReadOnlySpan<byte> data)
{
var reader = new SpanReader(data);
// 使用 reader...
} // reader 在方法结束时自动失效
// ? 错误使用
SpanReader? savedReader = null;
void BadUsage(ReadOnlySpan<byte> data)
{
savedReader = new SpanReader(data); // 编译错误
}
资源释放
// ? 使用 using 确保释放
using var writer = new PooledByteBufferWriter(1024);
// 使用 writer...
// ? 手动管理也可以
var writer = new PooledByteBufferWriter(1024);
try
{
// 使用 writer...
}
finally
{
writer.Dispose();
}
最佳实践总结
- 选择合适的类型
- 读取固定大小数据 →
SpanReader
- 写入固定大小数据 →
SpanWriter
- 动态大小写入 →
PooledByteBufferWriter
- 格式转换辅助 →
SpanHelper
- 性能优化
- 预估合适的缓冲区大小
- 批量操作减少调用次数
- 复用对象实例
- 内存管理
- 及时释放池化资源
- 避免持有 Span 引用超出生命周期
- 在高并发场景监控内存池使用
- 错误处理
- 检查边界和容量限制
- 处理编码转换异常
- 确保异常安全的资源释放
相关资源
?? 文档版本: 1.0
?? 更新时间: 2024年12月
?? 维护团队: NewLife 开发团队