![](/img/trans.png)
[英]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.