簡體   English   中英

在 C# 中使用 ArrayPool 重新使用 memory 從 String 到字節數組的轉換?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM