Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it faster to copy reference to object from dictionary or access it directly from dictionary?

Question is simple

is this code

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";
}

same fast as this code

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";
}

common sense tell me that it should be faster to look up the reference in dictionary once and store it somewhere so that it doesn't need to be looked up multiple times, but I don't really know how dictionary works.

So is it faster or not? And why?

like image 428
Petr Avatar asked Mar 15 '13 15:03

Petr


2 Answers

Yep, you are correct. Your first approach does the dictionary lookup 4 times, while the second does it once. The second is definitely better.

However, in real life, a dictionary lookup is ridiculously fast, so unless you've got a massive dictionary the difference won't be noticeable, maybe not even measurable.

like image 143
Joe Enos Avatar answered Oct 27 '22 13:10

Joe Enos


Joe's absolutely right, but as if it wasn't enough I've done a simple obvious test:

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; }
}

On my machine this outputs to:

3423
2113
Press any key to continue . . .

Having only 1 lookup definitely reduces the total time for big numbers.

like image 37
Alexander Tsvetkov Avatar answered Oct 27 '22 12:10

Alexander Tsvetkov