Ayende @ Rahien

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


+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…



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

Ayende Rahien

Well, that was fast.

Yep, that is it.


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.


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


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.


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.


  1. The worker pattern - 16 hours from now

There are posts all the way to May 30, 2016


  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


Main feed Feed Stats
Comments feed   Comments Feed Stats