簡體   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