4 ms·
I'm very disappointed that ref returns were not implemented as syntactic sugar for out params. A bit of history: game developers have been crying for a solutio
by zamalek 10y ago
I'm very disappointed that ref returns were not implemented as syntactic sugar for out params.
A bit of history: game developers have been crying for a solution to the matrix operator problem. A 4x4 matrix is 64 bytes of data. Implement the mathematical operators using C# operators and you're looking at 192 bytes copied per invocation. The workaround is the fake ref operator: void Add(ref Matrix, ref Matrix, out Matrix). The problem is that this results in code smell at the call sites. The ref return was the first compromise, allowing that method to become: ref Matrix Add(...). The ultimate solution would be to allow ref returns and ref parameters on operators, but you need ref returns first.
This feature misses all of that. Maybe we'll get out returns, but the argument against it would be language bloat, and even I'd agree. Sigh.
/rant
- deleted 10y ago[deleted]
- kukx 10y agoThe Add method signature could be simplified from void Add(ref Matrix, ref Matrix, out Matrix) to Matrix Add(ref Matrix, ref Matrix). Also, could you elaborate what you mean by out returns? Normal returns could be considered "out returns", no?
- bad_user 10y agoIf Matrix is a value type, then no, that's not the same thing, because with "out Matrix" it is passing it by reference, instead of by value.
- kukx 10y agoIsn't it in this case just an implementation detail without any meaningful consequences (apart from interop)? - I'm trying to find a way to benefit from it. I wrote some code to compare the two approaches and see what's going on underneath.[0] I'm not familiar with IL, but it seems like the memory usage is the same and the simple return function requires less ops. [0] http://tryroslyn.azurewebsites.net/#f:>ilr/A4VwRgNglgxgBDCBDAziuBhOBvAUHAuUSWOFAFwCcQZy4BlHfQl46eKAOzoA0BuZgQC+gouHZwAbgHsoAEzgB5EOQAU0lQzgAPAJRMWLbXAC8cTgFMA7luxwepuAEY4QgSxGtxpRgCULavp4hoSUASCUnObWtvaOAByu7oSehGykMvJwALKqQaIsjNrJIcpqGnR6JYbGZv6B1SJCQA== http://tryroslyn.azurewebsites.net/#f:>ilr/A4VwRgNglgxgBDCBD...
- zamalek 10y agoThis is no implementation detail and has nothing to do with overall memory use. It has to do with how much memory is copied (an operation that consumes time) per invocation. IL is the wrong level to look at this. In the by-value case: a stack frame of 192 bytes is allocated (+ space for other locals). The values of the matrices are copied into it from the parent stack frame (128 bytes). The method does its work and then calls "new Matrix". This occupies the final 64 bytes. Immediately this value is copied out of the method to the parent stack frame. In the by-ref case: a stack frame of 0 bytes is copied (+ space for other locals). The pointers to the two matrices are passed in, as well as a pointer to the memory for the result. The method does its work and then calls "new Matrix". The result of the .ctor is stored directly in the calling stack frame. You might consider that this is nit-picking, but consider that this has to happen 60 times per second. Calculating an MVP matrix for 1000 objects 60 times per second, results in 32MB of memory copied around per second. That assumes you are doing no additional math (which is definitely not the case). The performance benefit is substantial enough that even XNA had these overloads (which is where I think the workaround originated)[1]. [1]: https://msdn.microsoft.com/en-us/library/bb194950.aspx https://msdn.microsoft.com/en-us/library/bb194950.aspx
- bad_user 10y agoA return means copying that value on the stack and depending on its size, it can be expensive. In this case we're talking about a matrix, so that's not just one 32 or 64 bytes pointer.
- Locke1689 10y agoIt sounds like what you want there is RVMO?