0

主にパフォーマンスを重視するアプリケーションを作成しています。今日簡単なベンチマークを書いた後、ディクショナリ アクセス時間は配列アクセス時間よりも大幅に遅い (最大 100 倍) ことがわかりましたが、どちらも O(1) です。インターネットで同様の結果を見つけようとしましたが、役に立ちませんでした。これは正しいと思いますか?配列ではなく辞書にハッシュが関係しているので、私には理にかなっています。

私は現在、辞書の長所と短所を比較検討しており、より高速な実装を試みる必要があるかどうかを検討しています。私のアプリケーションの少なくとも 3 つのインスタンスで、foreach ループを使用してすべての辞書 (かなりの数があります) をループします。さて、私の質問に移りますが、foreach ループは「遅い」(ここでは比較的話します) ハッシュ プロセスを実行する必要がありますか? この場合、私は辞書に固執する可能性が高くなります。

追加情報として、アプリケーションは単純な 2D ゲームであり、辞書はゲーム エンティティに格納されます。本当に多いですけどね。はい、私はすでに実用的なソリューションを持っています。これは最適化前であり、最適化前ではありません。

これが私が書いたベンチマークです。私はこの分野の専門家ではないので、それは非常に間違っているかもしれません:

        public static int dict(Dictionary<key,int> dict, key k)
        {
            int i;
            //dict.TryGetValue(k,out i);
            i = dict[k];  //both these version yield the same results

            return i;
        }

        public static int arr(int[,] arr, key k)
        {
            int i;
            i = arr[k.x, k.y];

            return i;
        }

        public struct key
        {
            public int x, y;

            public key (int x, int y){
                this.x = x;
                this.y = y;
            }
        }

        public static void Main()
        {
            int dim = 256;
            Dictionary<key,int> dictVar = new Dictionary<key,int>(dim*dim*10);

            int[,] arrVar = new int[dim,dim];

            for (int i = 0; i < dim; ++i)
            {
                for (int j = 0; j < dim; ++j)
                {
                    arrVar[i, j] = i + j * i;
                    dictVar.Add(new key(i, j), i + i * j);
                }  
            }

            const int iterations = 1000000;
            key k = new key(200, 200);
            TestTime(dict, dictVar, k, iterations);
            TestTime(arr, arrVar, k, iterations);
        }

        public static void TestTime<T1, T2, TR>(Func<T1, T2, TR> action, T1 obj1,
                                                T2 obj2, int iterations)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            for (int i = 0; i < iterations; ++i)
                action(obj1, obj2);
            Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
        }
4

1 に答える 1

1

ループする内部リストを保持しますが、リストのタイプEntry<TKey, TValue>[]は であるため、毎回 KeyValuePair を作成する必要があります。これが減速の原因だと思います。

于 2012-05-17T22:30:02.513 に答える