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: 5,972 | Comments: 44,509

filter by tags archive

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…



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. Paying the rent online - 23 minutes from now
  2. Reducing parsing costs in RavenDB - about one day from now

There are posts all the way to Aug 04, 2015


  1. Production postmortem (5):
    29 Jul 2015 - The evil licensing code
  2. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats