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
Instead of newing a List you new up a delegate each call to GetOrAdd ?
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.
@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