Каков наиболее эффективный способ создания временной коллекции? Различия между stackalloc и выражениями коллекции? ⇐ C#
-
Anonymous
Каков наиболее эффективный способ создания временной коллекции? Различия между stackalloc и выражениями коллекции?
In C# there are now multiple ways to create a temporary collection.
You can just new an array and hope the garbage collector doesn't mind.
// Just create a new array Span array = new int[]{ 1, 2 }; In an unsafe context you can use stackalloc to create a temporary collection on the stack, reducing the load on the Garbage collector.
// Create a new array on the stack Span stack = stackalloc int[2]; stack[0] = 1; stack[1] = 2; But now with latest C# version you can also use a collection expression.
Span span = [1, 2]; I'm a bit confused on how the new collection expression works. Especially now Visual Studio suggest to convert the stackalloc to a collection expression. Which would suggest they are equivalent?
In general I don't just new an array in a performance critical section and tend to use the stackalloc. The new syntax for collection expressions is extremely convenient. But I can't really figure out how it works under the hood.
The C# specification suggests that when assigned to a Span the collection expression might become a stackalloc. But I'm unsure if/how this is currently implemented. I've tried looking at the IL representation in SharpLab gist. I'm not really used to looking at IL. But the collection expression and stackalloc definitely do not have the same IL representation. Does this suggest that it currently does not translate collection expressions to stackallocs?
// stackalloc ldc.i4.8 conv.u localloc ldc.i4.2 newobj instance void valuetype [System.Runtime]System.Span`1::.ctor(void*, int32) stloc.s 4 ldloc.s 4 stloc.1 ldloca.s 1 ldc.i4.0 call instance !0& valuetype [System.Runtime]System.Span`1::get_Item(int32) ldc.i4.1 stind.i4 ldloca.s 1 ldc.i4.1 call instance !0& valuetype [System.Runtime]System.Span`1::get_Item(int32) ldc.i4.2 stind.i4 // collection expressions ldloca.s 3 initobj valuetype 'y__InlineArray2`1' ldloca.s 3 ldc.i4.0 call !!1& ''::InlineArrayElementRef(!!0&, int32) ldc.i4.1 stind.i4 ldloca.s 3 ldc.i4.1 call !!1& ''::InlineArrayElementRef(!!0&, int32) ldc.i4.2 stind.i4 ldloca.s 3 ldc.i4.2 call valuetype [System.Runtime]System.Span`1 ''::InlineArrayAsSpan(!!0&, int32) stloc.2 Does anybody have a better understanding of how the new collection expression works under the hood and what the performance characteristics are, especially if it generates garbage?
Источник: https://stackoverflow.com/questions/781 ... rences-bet
In C# there are now multiple ways to create a temporary collection.
You can just new an array and hope the garbage collector doesn't mind.
// Just create a new array Span array = new int[]{ 1, 2 }; In an unsafe context you can use stackalloc to create a temporary collection on the stack, reducing the load on the Garbage collector.
// Create a new array on the stack Span stack = stackalloc int[2]; stack[0] = 1; stack[1] = 2; But now with latest C# version you can also use a collection expression.
Span span = [1, 2]; I'm a bit confused on how the new collection expression works. Especially now Visual Studio suggest to convert the stackalloc to a collection expression. Which would suggest they are equivalent?
In general I don't just new an array in a performance critical section and tend to use the stackalloc. The new syntax for collection expressions is extremely convenient. But I can't really figure out how it works under the hood.
The C# specification suggests that when assigned to a Span the collection expression might become a stackalloc. But I'm unsure if/how this is currently implemented. I've tried looking at the IL representation in SharpLab gist. I'm not really used to looking at IL. But the collection expression and stackalloc definitely do not have the same IL representation. Does this suggest that it currently does not translate collection expressions to stackallocs?
// stackalloc ldc.i4.8 conv.u localloc ldc.i4.2 newobj instance void valuetype [System.Runtime]System.Span`1::.ctor(void*, int32) stloc.s 4 ldloc.s 4 stloc.1 ldloca.s 1 ldc.i4.0 call instance !0& valuetype [System.Runtime]System.Span`1::get_Item(int32) ldc.i4.1 stind.i4 ldloca.s 1 ldc.i4.1 call instance !0& valuetype [System.Runtime]System.Span`1::get_Item(int32) ldc.i4.2 stind.i4 // collection expressions ldloca.s 3 initobj valuetype 'y__InlineArray2`1' ldloca.s 3 ldc.i4.0 call !!1& ''::InlineArrayElementRef(!!0&, int32) ldc.i4.1 stind.i4 ldloca.s 3 ldc.i4.1 call !!1& ''::InlineArrayElementRef(!!0&, int32) ldc.i4.2 stind.i4 ldloca.s 3 ldc.i4.2 call valuetype [System.Runtime]System.Span`1 ''::InlineArrayAsSpan(!!0&, int32) stloc.2 Does anybody have a better understanding of how the new collection expression works under the hood and what the performance characteristics are, especially if it generates garbage?
Источник: https://stackoverflow.com/questions/781 ... rences-bet
Мобильная версия