Home > database >  Performance of returning an expression vs assigning the expression to an object and returning it
Performance of returning an expression vs assigning the expression to an object and returning it

Time:12-19

Are any performance implications of just returning an expression vs assigning the return value of the expression to a variable and returning that.

This is an example of returning an expression

public IList<Employee> GetEmployees()
{
    return mapper.Map<IList<EmployeeDto>>(employees);
}

Vs return a variable

public IList<Employee> GetEmployees()
{
    var employees = mapper.Map<IList<EmployeeDto>>(employees);
    return employees;
}

I find the second option more readable and easy to see the value of the mapping result when debugging. I would like to know if there are any performance issues when going for the second option especially in terms of garbage collection as a new variable is created and assigned to the reference type object.

CodePudding user response:

Creating a variable does obviously keep the object in memory but you're just returning a reference to that object, returning the object also creates a temporary object in memory so that it can be returned. Technically just returning the object straight away without creating a variable is faster but the difference is negligible it is basically just a preference when writing clean code.

A similar question was asked relating to Java.

CodePudding user response:

Always go for readability.

The performance and memory impact of introducing the variable is negligible. Lets look at the steps (assuming a naive runtime system):

  • mapper.Map<IList<EmployeeDto>>(_employees) creates an object on the heap. Happens in both versions.

  • var employees = ... creates a variable on the stack that references this heap object. This consumes probably 8 bytes of stack, which is negligible. It causes one write access into memory. And it creates a "reachability path" to the object, which prevents the GC from reclaiming the object (from that line on, you can "reach" the object by the expression employees, and the GC must not reclaim objects that can be reached by a valid C# expression).

  • return employees; places the object reference onto the stack as the method's return value. This happens in both versions. The second version needs to read the value from memory, so it's one additional memory read. And it creates a second "reachability path" to the object, which also prevents the GC from reclaiming the object.

  • } removes all method-local entries from the stack, in our case the employees variable, thus removing one "reachability path" to our object. The other one (return value on the stack) remains intact, still preventing the GC from reclaiming the object. Most prabably, your caller will use the return value object, meaning that in the calling code there will be some "reachability path" to protect the object from being garbage-collected as long as the caller needs it.

So, there is no duplication of the employees list itself, just one additional reference, consuming 8 bytes. And there are two additional memory accesses, one write and one read access. But it's quite probable that (outside of a debugging session) the runtime system optimizes away your variable, so that even these tiny difference no longer exist.

Regarding GC, the additional "reachability path" created through the variable only lives for a very short time. And it marks an object as reachable that is needed anyway. If instead, you were to store a reference to the object in some static field, of course then it would be reachable through this field "forever", causing something that we might call a "memory leak", but that's not the case in your code.

  • Related