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


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. 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

RECENT SERIES

  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

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats