[英]Re-use memory from String to byte array conversion with ArrayPool in C#?
是否可以重新使用在字符串到字節數組轉換中使用的 memory?
應用程序必須以 60fps 的速度通過網絡發送大字符串。 這似乎給 GC 帶來了太大的壓力。 那么是否有可能以某種方式重新使用字符串轉換創建的字節 arrays 呢?
這些是我當前的序列化方法:
public static byte[] SerializeJson(DrawDescriptionLayer layer)
{
var s = JsonConvert.SerializeObject(layer, js);
return Encoding.UTF8.GetBytes(s); //rent from array pool here
}
或者使用流:
public static byte[] SerializeJson2(DrawDescriptionLayer layer)
{
using (var ms = new MemoryStream())
using (StreamWriter writer = new StreamWriter(ms, Encoding.UTF8))
using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
{
JsonSerializer ser = JsonSerializer.Create(js);
ser.Serialize(jsonWriter, layer);
jsonWriter.Flush();
return ms.ToArray(); //rent from array pool here
}
}
我知道我應該編寫一個自定義二進制序列化程序,但 Newtonsoft.Json 開箱即用,該應用程序使用沒有序列化屬性的第三方類型。
如果性能和 memory 分配是主要問題,您應該強烈考慮使用utf8json 。
utf8json 不是同時使用緩慢的JsonConvert.SerializeObject
方法,然后是分配繁重的UTF8.GetBytes
,而是一次完成:
public byte[] SerializeJson(DrawDescriptionLayer layer)
{
return Utf8Json.JsonSerializer.Serialize(layer, Utf8Json.Resolvers.StandardResolver.Default);
}
該庫針對性能和低分配進行了優化,並用於 ElasticSearch 推薦的 .NET 客戶端等軟件中。
還要確保DrawDescriptionLayer
是一個 DTO,它針對廉價的 JSON 序列化進行了高度優化,並且不包含 .network 傳輸中未使用的任何內容。
祝你好運!
就流而言, Microsoft.IO.RecyclableMemoryStream是專門為減少頻繁大量分配產生的垃圾 collections 的成本而創建的。 您可以修改您的 stream 示例,例如:
private static readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager();
public static byte[] SerializeJson2(DrawDescriptionLayer layer)
{
using (var ms = _manager.GetStream())
using (StreamWriter writer = new StreamWriter(ms, Encoding.UTF8))
using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
{
JsonSerializer ser = JsonSerializer.Create(js);
ser.Serialize(jsonWriter, layer);
jsonWriter.Flush();
return ms.ToArray();
}
}
但是,使用 ToArray() 會復制到一個從未合並的新數組中,根據文檔“...完全消除了 RecyclableMemoryStream 的許多好處。”。 所以考慮改用 GetBuffer() 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.