4 ms·
Unfortunately, while I would love JIT to do such kind of optimizations, this is completely not how it works today. First and foremost, '&mut' in Rust is a muta
by neonsunset 4y ago
Unfortunately, while I would love JIT to do such kind of optimizations, this is completely not how it works today.
First and foremost, '&mut' in Rust is a mutable reference. The C# alternative is just 'ref'. Both point to specific addresses. 'Box<T>' OTOH is a handle for a struct allocated on a heap, just like C#'s one is implementation-wise (except in C# they are further managed by runtime but that's besides the point).
Now regarding the arrays - 'T[]' is strictly object withouts ifs and buts. There is no "short array" optimisation that would substitute array type with stack-allocated inline buffer. If you want this, you have to write it manually. See: https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs#L46 https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6b...
The last but not least, if the method signature accepts an argument by its interface type e.g. 'HandleEnumerable<T>(IEnumerable<T> values)', then the IEnumerable-implementing struct will be boxed before method can be called. C#/.NET doesn't do full generic monomorphization like Rust. Instead, for class-type generics a common '_Canon' method body will be JITted which will also implicitly accept generic-type arguments to correctly dispatch on an actual <T> of the method. OTOH, for structs, all method calls will be fully monomorphized per each struct type. This means that you can avoid struct boxing when dispatching by interface by rewriting method signature to 'HandleEnumerable<T, TEnumerable>(TEnumerable values) where TEnumerable : IEnumerable<T>'. In this case, unless you cast your struct to an interface type explicitly beforehand, the struct will not be boxed.
For the sake of simplicity, this explanation scope doesn't include advanced optimisations done by Tier-1 JIT compilation such as guarded de-virtualization, more aggressive inlining that can potentially elide boxing, etc.
- WorldMaker 4y agoAgain, I still believe you are confusing lower-case CLR `object` (top-type) and upper-case BCL `System.Object` (root-type of "reference types"/"heap types" and below the top-type; they are confusingly named to allow for some abstractions where considering them the same thing makes it easier to reason with, but they are different concerns). Value types in stack space (function locals/small scoped variables) that fit entirely in stack space (size restrictions; "short arrays") never get "boxed" to the heap. `stackalloc` is an important need to restrict such types to the stack, because things like Span<T> require stack types and stack types only, but the general JIT rules apply that value types that don't leave stack scopes often are never "boxed" to the heap, including "short arrays" in function local scopes. (With the complicating caveat that things like async/await change what "function local" means and will increase boxing as things move to async state closures.)
- neonsunset 4y agoYou are free to believe this but if you want me to believe you, please provide official spec or code that says it works that way today. Because making your statements sound reasonable doesn't magically make them true - the truth is far removed from your statements, sorry for putting it bluntly. JIT never did proper escape analysis for object stack allocation except for the small proposal prototype implementation which the runtime team decided to put away for better times: https://github.com/dotnet/runtime/issues/11192 https://github.com/dotnet/runtime/issues/11192 It is never enabled and will not work the way you expect it to even if you try. Huh, now that I think about it, this account might be posting messages generated by GPT-3 and I'm just wasting time.
- WorldMaker 4y agoThe fundamentals of Value Types versus Reference Types: https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/value-types-and-reference-types https://docs.microsoft.com/en-us/dotnet/visual-basic/program... What you linked is an issue regarding storing Reference Types (classes) in stack space. Again, there is a difference in .NET between a Reference Type and Value Type, and this is a fundamental dichotomy going back to the earliest days of .NET. I don't appreciate the ad hominem attack and suggest that you google any further follow ups yourself.
- neonsunset 4y agoC# arrays are 'object', aka "Reference Type". The only reason I'm responding the way I do is because GPT-3 is too known for writing elaborate texts despite consistently getting fundamentals wrong. Your previous reply directly contradicts runtime implementation so I see no reason to apologize for my statements. In addition, regarding Span<T> and other ref structs, they can hold any type and have no restriction to T : unmanaged. That's because objects by their nature of being on the heap are guaranteed to outlive the lifetime of any ref struct and the runtime supports tracking GC references held like this anyway.