繁体   English   中英

如何通过单个写操作用单个值填充整个数组指针?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM