[英]How can I always capture the entire content of a network stream read in a single operation of an asynchronous read callback function?
[英]How can you fill an entire array pointer with a single value with a single write operation?
我有一個指向字節數組的指針,我需要將這個數組的某個區域的值設置為 0。我非常熟悉通過 Marshal/Buffer/Array 類可用的方法,這個問題不在都很難。
然而,問題是我不想創建過多的 arrays,或者一個字節一個字節地寫。 不過,我熟悉的所有方法都需要完整的 arrays,而且它們顯然不適用於單個值。
我見過幾種 C 方法可以實現我正在尋找的結果,但我不相信我可以訪問這些方法而不包括整個 C 庫,或者不編寫特定於平台的代碼。
我當前的解決方案如下所示,但我想在不分配新字節數組的情況下實現這一點。
Marshal.Copy(new byte[Length], 0, ptr + offset, length);
那么在 C# 或非托管語言/庫中是否有一種方法,我可以使用它來以某個偏移量和某個長度用一個值 (0) 填充數組(通過指針)?
奇跡般地,當我問什么是解決這個問題的好方法時,ChatGPT 非常接近。 它沒有弄清楚,但它建議我使用跨度。
因此,這是我想出的解決方案:
Span<byte> span = new Span<byte>(ptr + offset, Length);
span.Fill(0);
該解決方案比必須為非常大的 arrays 分配字節數組快大約 25 倍。
示例基准:
int size = 100_000;
nint ArrayPointer = Marshal.AllocHGlobal(size);
int trials = 1_000_000;
// Runtime was 1582ms
Benchmark("Fill with span", () =>
{
Span<byte> span = new Span<byte>((void*) ArrayPointer, size);
span.Fill(0);
}, trials);
// Runtime was 40681ms
Benchmark("Fill with allocation", () =>
{
Marshal.Copy(new byte[size], 0, ArrayPointer, size);
}, trials);
// Far too slow to get a result with these settings
Benchmark("Fill individually", () =>
{
for (int i = 0; i < size; i++)
{
Marshal.WriteByte(ArrayPointer + i, 0);
}
}, trials);
// Results with size = 100_000 and trials = 100_000
// Fill with span: 176ms
// Fill with allocation: 4382ms
// Fill individually: 24672ms
您可以為此使用 Fill
arrayName.Fill('X',4,10) // fill character array at index 4 for 10 elements with character X
https://learn.microsoft.com/en-us/do.net/api/system.array.fill?view.net-7.0
注意:C# 的文檔非常好。 你可以go到網站,查看數組的所有方法。 如果您真的關心這是如何實現的,您甚至可以撥打 go 至 github 並閱讀源代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.