As a C# developer you got used to apply anonymous functions everywhere. Everytime you write a LINQ statement or use a lamdbda expression, you are creating an anonymous function.
But what you maybe are not aware of is that anonymous functions have a performance impact and don’t come cheap:
- Overhead of a delegate invocation (very very small, but it does exist).
- 2 heap allocations if a lambda captures local variable or argument of enclosing method (one for closure instance and another one for a delegate itself).
- 1 heap allocation if a lambda captures an enclosing instance state (just a delegate allocation).
- 0 heap allocations only if a lambda does not capture anything or captures a static state.
One way to limit the number of allocations is through local functions but today I want to focus on another option; using static anonymous functions.
Let’s use a really simple example where static anonymous functions can help:
In the example above we capture the value ‘addition’, causing an unintended allocation. To fix it we can change the implementation to use a static anonymous function. Therefore we have to apply the const
modifier on the variable and add the static
modifier to the lambda:
Some rules apply when you want to use static anonymous functions:
- A static anonymous function cannot capture state from the enclosing scope. As a result, locals, parameters, and
this
from the enclosing scope are not available within a static anonymous function. - A static anonymous function cannot reference instance members from an implicit or explicit
this
orbase
reference. - A static anonymous function may reference
static
members from the enclosing scope. - A static anonymous function may reference
constant
definitions from the enclosing scope.