7

質問は簡単です

このコードは

public Dictionary<string, SomeObject> values = new Dictionary<string, SomeObject>();

void Function()
{
    values["foo"].a = "bar a";
    values["foo"].b = "bar b";
    values["foo"].c = "bar c";
    values["foo"].d = "bar d";
}

このコードと同じ速さ

public Dictionary<string, SomeObject> values = new Dictionary<string, SomeObject>();

void Function()
{
    var someObject = values["foo"];
    someObject.a = "bar a";
    someObject.b = "bar b";
    someObject.c = "bar c";
    someObject.d = "bar d";
}

常識的に言えば、辞書で参照を一度検索して、何度も検索する必要がないようにどこかに保存する方が速いはずですが、辞書がどのように機能するかはよくわかりません。

それで、それは速いかどうか?なぜ?

4

3 に答える 3

7

ええ、あなたは正しいです。最初のアプローチでは辞書検索が 4 回行われますが、2 番目の方法では 1 回行われます。2番目は間違いなく優れています。

ただし、実際の辞書検索は非常に高速であるため、大規模な辞書を使用しない限り、その違いは目立たないか、測定できない可能性があります。

于 2013-03-15T15:05:24.937 に答える
6

ジョーは完全に正しいですが、それだけでは不十分であるかのように、単純で明白なテストを行いました。

static void Main(string[] args)
{
    var dict = new Dictionary<string, Foo>();
    var number = 10000000;
    for (int i = 0; i < number; i++)
    {
        dict[i.ToString()] = new Foo();
    }

    var watch = new Stopwatch();

    watch.Start();
    for (int i = 0; i < number; i++)
    {
        var key = i.ToString();
        dict[key].A = "a";
        dict[key].B = "b";
        dict[key].C = "c";
        dict[key].D = "d";
    }

    watch.Stop();
    Console.Out.WriteLine(watch.ElapsedMilliseconds);

    watch.Reset();

    watch.Start();
    for (int i = 0; i < number; i++)
    {
        var key = i.ToString();
        var foo = dict[key];

        foo.A = "a";
        foo.B = "b";
        foo.C = "c";
        foo.D = "d";
    }

    watch.Stop();
    Console.Out.WriteLine(watch.ElapsedMilliseconds);
}   

class Foo
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
}

私のマシンでは、これは次のように出力されます。

3423
2113
Press any key to continue . . .

ルックアップを 1 回だけにすることで、大きな数の合計時間を確実に短縮できます。

于 2013-03-15T15:37:59.813 に答える
1

興味がありました。次の単体テストは、(おそらく) 2 番目の方法が約 25% 高速であることを示しています。(121 ミリ秒対 91 ミリ秒)。6 フィールドから 2 フィールドにすると、ギャップが 40 ミリ秒から 33 ミリ秒に短縮されました。私はこれをかなり早く書いたのでおそらく言います、そしてそれが何らかの副作用を測定することに対して免疫があるとは確信していませんが、それは予想される動作を示しているので、なぜそれを疑問視するのですか. (はぁ)。

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;

namespace TestProject1
{

public class DataObject
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
    public string E { get; set; }
    public string F { get; set; }
}

[TestClass]
public class UnitTest1
{
    public static Dictionary<string, DataObject> dict = new Dictionary<string, DataObject>();
    static string lookie;

    [ClassInitialize()]
    public static void MyClassInitialize(TestContext testContext) {

        Random rand = new Random(123545);
        for (int i = 0; i < 10000; i++)
        {
            string key = rand.NextDouble().ToString();
            DataObject dob = new DataObject();
            dict.Add(key, dob);
            if (i == 4567)
                lookie = key;
        }

    }


    [TestMethod]
    public void TestMethod()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int j = 0; j < 100000; j++)
        {
            dict[lookie].A = "val" + j;
            dict[lookie].B = "val" + j;
            dict[lookie].C = "val" + j;
            dict[lookie].D = "val" + j;
            dict[lookie].E = "val" + j;
            dict[lookie].F = "val" + j;
        }
        sw.Stop();

        System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds);

        sw.Reset();
        sw.Start();
        for (int j = 0; j < 100000; j++)
        {
            DataObject dob = dict[lookie];
            dob.A = "val" + j;
            dob.B = "val" + j;
            dob.C = "val" + j;
            dob.D = "val" + j;
            dob.E = "val" +j;
            dob.F = "val" +j;
        }
        sw.Stop();

        System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds);
    }
  }
}
于 2013-03-15T15:32:47.830 に答える