Extend operators of T
to operators of T[]
#2656
Replies: 10 comments
-
Arrays are not commonly used as types for doing calculations on. IEnumerable is more commonly used, especially given that it has the advantage of not allocating many intermediate arrays when processing a collection in a pipeline. Is there any reason this should apply just to arrays? |
Beta Was this translation helpful? Give feedback.
-
There is currently no way for the C# compiler to know if a method has side effects, since it can't see inside a method which is defined in another assembly. Changing this would be a huge task in and of itself, and would make this feature request pale in comparison. |
Beta Was this translation helpful? Give feedback.
-
I don't feel that C# needs to be extended to adequately support this. Maybe extend the |
Beta Was this translation helpful? Give feedback.
-
Wouldn't extension operators (i.e extension everything) partially fix this problem? Might be mistaken though. |
Beta Was this translation helpful? Give feedback.
-
@ja72: We had the same problem, first problem was that there are no math operations defined on T since there is no numeric type. This has been very often discussed here. The other problem is why we got rid of operators on arrays is that if you have very large arrays, intermediate arrays are created which puts some load on the GC (of course depending on the size of the arrays). Our case ist something like 512x512, 1024x1024, 2048x2048 or even more. Sometimes we have volume data float: 512x512x512, lets say you have a volume A, B and C of the mentioned size and you need to write something like this:
Every step creates an intermediate data volume that lands in the LOH. So you are putting a lot of pressure on the GC. What we did, and I personally still don't like the approach is to resolve the whole expression into one by resolving some formula that is given as string (because I haven't found a better way) using the C# runtime compiler, so our method looks like this, I won't go into details now, just give you the clue:
for the above mentioned equation you will write
If you resolve it via runtime code compilation you end up by allocating and running through the data only once, and not 6 times. The performance gain and less memory consumption is enormous. For all other primitive operations math, we created methods, assume capital letter are arrays, lowercase letters are scalar values:
For performance reasons, we are have methods to return the result into an already allocated array:
As you can see we have managed to use the T which included most primitive value types by writing the necessary math in CIL. As you can imagine the library has a lot of lines since +,-,*,/ have to implemented. But there are a lot of additional operator that e.g. System.Math support. You can think of Pow, Log, Sqrt and many more. I absolutely hate this approach, but for performance reasons I see no better way currently. |
Beta Was this translation helpful? Give feedback.
-
You are suggesting IEnumerable instead of regular "native" arrays. Have you benchmarked the difference between using IEnumerable and Array? It would be interesting to hear your results or see your approach. My tests always ended up with the best performance working with unsafe code and pointers. Although the IEnumerable would be the most generic approach I found it's the slowest. |
Beta Was this translation helpful? Give feedback.
-
It is possible to use generics to remove the performance costs that are associated with Linq and IEnumerable. See #2482. Whilst that is pretty ugly without language support, if you only wanted this to work with arrays used as the backing collection it would be possible to make it much simpler. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt : I have read your exploration in your post, that was excellent work. I was not really sure if your descriptions currently work, or they are only a future excursion of what could be possible. On the other hand, since Span came up, I'm really not quite sure if using Span for those things wouldn't be better, at least when it comes to slicing. |
Beta Was this translation helpful? Give feedback.
-
I agree that this is good feature but I strongly disagree to just extend to be like that automatically We should have some other syntax to distinguish the intentionally operation on array and parallellizing Maybe double[] A = new[] { 1.0, 2.0, 3.0, 4.0, 5.0 };
double[] B = 1.0 + foreach(A) / 2.0; // syntax foreach(collection) become select((item) => func(item)) Another problem is double[] C = A - B; What happen if |
Beta Was this translation helpful? Give feedback.
-
Hardware intrinsics is out https://devblogs.microsoft.com/dotnet/hardware-intrinsics-in-net-core/ |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Make arrays a first-class citizen by allowing functions that are defined for the element types to be applied to the collections and slices. Imagine if you could write code like this
and handle every error of type
CS0019 Operator '-' cannot be applied to operands of type 'double[]' and 'double[]'
orCS0019 Operator '/' cannot be applied to operands of type 'double[]' and 'double'
with compiler-generated code of the formMy proposal extends definitions of functions/methods and operators of type
T
to alsoT[]
by applying them to all the elements of an array. In addition, the compiler can produce numerically optimized code (loop unrolling, vectorization). Although the inspiration for this is numerical simulations and languages like Fortran and Matlab, as well as the pythonmap(operator.add, a, b)
operations, the usages can extend to any array of structures.Fortran can do this with
elemental
functions(no side effects), and so the C# compiler should be able to distinguish which operators and functions can be used in this way.Beta Was this translation helpful? Give feedback.
All reactions