Ayende @ Rahien

It's a girl

Small optimizations? Did you check that idiot checkbox yet?

I started to write the following code:

operationsInTransactions.GetOrAdd(txId,  new List<Command>())
    .Add(new Command
    {
        Key = key,
        Position = position,
        Type = CommandType.Put
    });

But then I realized that in the happy path, I would always allocate a list, even if I don’t need it, and I changed it to this:

operationsInTransactions.GetOrAdd(txId, guid => new List<Command>())
    .Add(new Command
    {
        Key = key,
        Position = position,
        Type = CommandType.Put
    });

Why am I being stupid?

Hint: It has nothing to do with the stupidity associated with trying to do micro optimizations…

Comments

Torkel
10/13/2010 10:21 AM by
Torkel

Instead of newing a List you new up a delegate each call to GetOrAdd ?

Ayende Rahien
10/13/2010 10:24 AM by
Ayende Rahien

Well, that was fast.

Yep, that is it.

tobi
10/13/2010 10:27 AM by
tobi

No! I think the C# compiler caches delegates that do not close over variables. I have seen that in reflector a while ago. The delegate gets written to a static field.

Dennis
10/13/2010 12:03 PM by
Dennis

Even so, the speed at which this allocation happens makes it just an insane micro optimization... Unless you are doing it billions of times.

configurator
10/13/2010 05:41 PM by
configurator

Tobi is right. Non-closing delegates are converted to static methods. I don't know what happens to ones that use fields, but I'm pretty sure they're cached as well. Only when closing over locals you're creating a mess.

Matt Warren
10/13/2010 11:53 PM by
Matt Warren

@configurator I think that if it uses fields it gets converted into a instance method, but I'm not entirely sure.

Daniel
10/14/2010 02:36 PM by
Daniel

If a delegate closes over local variables, a helper class gets created, so a lambda translates into 2 allocations: the helper class and the delegate.

If a delegate closes only over 'this', it gets compiled into an instance method. These aren't cached, so the lambda causes 1 allocation: the delegate.

If a delegate doesn't close over any variables, then it gets compiled into a static method, and the delegate gets cached using a static field. Once the cache is filled, the lambda doesn't cause any heap allocations.

Comments have been closed on this topic.