Search code examples
c#.netunity-game-engineclrnullable

Nullable types boxing in performance recommendations


Extracted from Unity perfomance documentation:

Example of problematic boxing via nullable value types

This code demonstrates a dummy particle class that one may create in a Unity project. A call to TryGetSpeed() will cause object allocation on the heap which will need to be garbage collected at a later point in time. This example is particularly problematic as there may be 1000+ or many more particles in a scene, each being asked for their current speed. Thus, 1000's of objects would be allocated and consequently de-allocated every frame, which would greatly diminish performance. Re-writing the function to return a negative value such as -1 to indicate a failure would avoid this issue and keep memory on the stack.

public class MyParticle
{
   // Example of function returning nullable value type
   public int? TryGetSpeed()
   {
       // Returns current speed int value or null if fails
   }
}

Is this correct?

A local value type should be allocate in the stack (if it is not in an anonymous method or an iterator block). Why if return a nullable value type, this will be allocate in the heap?

And why am I going to keep memory on the stack returning a value type?


Solution

  • Is this correct?

    No, it's not correct. int? is the same as Nullable<int>, which is still a value type, and which is still returned from the method without a heap allocation, and without boxing.

    And it seems that Microsoft has noticed this erroneous passage in the documentation, because it's been removed. Here's a cached version of the page, with the passage included.

    I assume this change was recent, because I further assume that when you posted the link to the documentation page, it actually did include that passage, hence the question itself. But the page definitely does not include that passage now. Indeed, there was an issue opened on Github concerning this exact passage, and that issue was closed (so, presumably fixed) two hours ago (midday on November 7, 2020, PST).

    That said, please note: the stack is an implementation detail. Using value types can (as in this case) avoid the need to allocate on the heap, but value types can and do live on the heap in other scenarios, and so if one is concerned about heap vs stack allocations, one needs to base one's predictions on something other than strictly the question of value vs reference type.