Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 6,128 | Comments: 45,550

filter by tags archive

Small optimizations? Did you check that idiot checkbox yet?

time to read 2 min | 296 words

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

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

Ayende Rahien

Well, that was fast.

Yep, that is it.

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

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

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

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

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.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. The worker pattern - 16 hours from now

There are posts all the way to May 30, 2016

RECENT SERIES

  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats