web-dev-qa-db-ja.com

配列をすばやくゼロにする方法は?

現在forループで実行しています。CにはZeroMemory APIがあることを知っていますが、C#では使用できないようです。また、Javaからの多少同等のArray.fillも存在しません。もっと簡単な方法がありますか?

54
esac

Array.Clear() を試してください:

要素の種類に応じて、配列の要素の範囲をゼロ、false、またはnull(Visual BasicではNothing)に設定します。

103
Jason Punyon
  • C++:memset(array, 0, array_length_in_bytes);

  • C++ 11:array.fill(0);

  • C#:Array.Clear(array, startingIndex, length);

  • Java:Arrays.fill(array, value);

48
Chap
Array.Clear(integerArray, 0, integerArray.Length);
16
Dustin Getz

[〜#〜] update [〜#〜]

Array.Clear()およびarray[x] = default(T)のパフォーマンスに関する ベンチマーク に基づいて、2つの主要なケースがあると述べることができます配列をゼロ化するときに考慮される:

A)1..76アイテムの長さの配列があります;

B)77以上の項目長の配列があります。

したがって、プロット上のorange行はArray.Clear()アプローチを表します。

プロットのblue行はarray[x] = default(T)アプローチ(配列の反復とその値のdefault(T)への設定)を表します)。

enter image description here

このジョブを実行するヘルパーを次のように一度書くことができます:

public static class ArrayHelper
{
    // Performance-oriented algorithm selection
    public static void SelfSetToDefaults<T>(this T[] sourceArray)
    {
        if (sourceArray.Length <= 76)
        {
            for (int i = 0; i < sourceArray.Length; i++)
            {
                sourceArray[i] = default(T);
            }
        }
        else { // 77+
             Array.Clear(
                 array: sourceArray,
                 index: 0,
                 length: sourceArray.Length);
        }
    }
}

使用法:

someArray.SelfSetToDefaults();
14
AndreyWD

何人かの人々が回答を投稿し、それらを削除して、どの言語でもforループはmemsetやFillMemoryなどと同等のパフォーマンスを発揮すると言っています。

例えば、コンパイラーは、64ビットのゼロ割り当て命令を利用できるように、それを64ビットにアライメントされた断片にチャンクする場合があります。アライメントとスタッフを考慮に入れます。 Memsetの実装は確かに簡単ではありません。

one memset.asmmemset-is-faster-than-simple-loop.html も参照してください。

コンパイラおよび標準ライブラリライターの無限の不正を過小評価しないでください。

12
Dustin Getz

Dll importを使用してメソッドを呼び出す。高速で使いやすい:)

 [DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
 public static extern IntPtr MemSet(IntPtr dest, int c, int byteCount);

cは、メモリに設定する値です

OR

[DllImport("kernel32.dll", EntryPoint="RtlZeroMemory")]
public unsafe static extern bool ZeroMemory(byte* destination, int length);

これは、指定された配列をゼロに設定するだけです

2
Reaven Clan