1

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?

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
Juxant
  • 106
  • 6
  • 1
    I don't understand what the documentation is trying to say there: if you simply call `int? speed = someParticle.TryGetSpeed()`, that will not box. Perhaps the author is getting confused with Java, where returning an `Integer` _will_ box – canton7 Dec 07 '20 at 13:45
  • 2
    Looks like [someone already opened an issue about this](https://github.com/MicrosoftDocs/mixed-reality/issues/128) – canton7 Dec 07 '20 at 13:46
  • 2
    "A local value type should be allocate in the stack" This is not a true statement, even with your qualifications. There are numerous more qualifications. It *may* allocate on the stack. That said, the stack is an implementation detail rarely worth considering in all but pretty few niche situations. You can often discuss whether a variable is boxed or not productively (because that is unambiguously true or false, and is documented as such, when considering a sufficiently complete program), but you should not be assuming that any non-boxed value type is on the stack. – Servy Dec 07 '20 at 13:55
  • In most cases the better way in my opinion would be `public bool TryGetSpeed(out int speed){ ... }` where the method returns `true` if it succeeds. – derHugo Dec 07 '20 at 14:07
  • @derHugo If you're writing your program in C# 1.0 and don't have nullable value types, sure, I guess. If you're writing a modern program, no, not really. – Servy Dec 07 '20 at 14:11
  • @Servy why? what would be the difference between a `null` check of the bool return? – derHugo Dec 07 '20 at 14:14
  • @derHugo The ability to pass the return value as a single value to somewhere else rather than needing to pass along two separate values until you're ready to use them. `out` values also behave rather poorly with many constructs, such as lambdas, functional programming design, etc. It's also useful if you don't need the result to be stored in a variable, and instead want to use it as an expression. – Servy Dec 07 '20 at 14:21
  • @Sevry fair enough. I didn't think about passing it further on only the immediate usage tbh, so yeah good point. – derHugo Dec 07 '20 at 14:39

1 Answers1

2

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.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • [Here's the commit](https://github.com/MicrosoftDocs/mixed-reality/commit/6d55215a45bbb9a782a602b410ed30a90aa26883) – canton7 Dec 08 '20 at 09:07