Is c# compiler deciding to use stackalloc by itself?

吃可爱长大的小学妹 提交于 2019-12-23 11:59:28

问题


I found a blog entry which suggests that sometimes c# compiler may decide to put array on the stack instead of the heap:

Improving Performance Through Stack Allocation (.NET Memory Management: Part 2)

This guy claims that:

The compiler will also sometimes decide to put things on the stack on its own. I did an experiment with TestStruct2 in which I allocated it both an unsafe and normal context. In the unsafe context the array was put on the heap, but in the normal context when I looked into memory the array had actually been allocated on the stack.

Can someone confirm that?
I was trying to repeat his example, but everytime I tried array was allocated on the heap.

If c# compiler can do such trick without using 'unsafe' keyword I'm specially intrested in it. I have a code that is working on many small byte arrays (8-10 bytes long) and so using heap for each new byte[...] is a waste of time and memory (especially that each object on heap has 8 bytes overhead needed for garbage collector).

EDIT: I just want to describe why it's important to me:
I'm writing library that is communicating with Gemalto.NET smart card which can have .net code working in it. When I call a method that returns something, smart card return 8 bytes that describes me the exact Type of return value. This 8 bytes are calculated by using md5 hash and some byte arrays concatenations.
Problem is that when I have an array that is not known to me I must scan all types in all assemblies loaded in application and for each I must calculate those 8 bytes until I find the same array.
I don't know other way to find the type, so I'm trying to speed it up as much as possible.


回答1:


From your line:

I have a code that is working on many small byte arrays (8-10 bytes long)

Personally, I'd be more interested in allocating a spare buffer somewhere that different parts of your code can re-use (while processing the same block). Then you don't have any creation/GC to worry about. In most cases (where the buffer is used for very discreet operations) with a scratch-buffer, you can even always assume that it is "all yours" - i.e. every method that needs it can assume that they can start writing at zero.

I use this single-buffer approach in some binary serialization code (while encoding data); it is a big boost to performance. In my case, I pass a "context" object between the layers of serialization (that encapsulates the scratch-buffer, the output-stream (with some additional local buffering), and a few other oddities).




回答2:


Author of the linked-to article here.

It seems impossible to force stack allocation outside of an unsafe context. This is likely the case to prevent some classes of stack overflow condition.

Instead, I recommend using a memory recycler class which would allocate byte arrays as needed but also allow you to "turn them in" afterward for reuse. It's as simple as keeping a stack of unused byte arrays and, when the list is empty, allocating new ones.

Stack<Byte[]> _byteStack = new Stack<Byte[]>();

Byte[] AllocateArray()
{
Byte[] outArray;
if (_byteStack.Count > 0)
  outArray = _byteStack.Pop(); 
else
  outArray = new Byte[8];
return outArray;
}

void RecycleArray(Byte[] inArray)
{
  _byteStack.Push(inArray);
}

If you are trying to match a hash with a type it seems the best idea would be to use a Dictionary for fast lookups. In this case you could load all relevant types at startup, if this causes program startup to become too slow you might want to consider caching them the first time each type is used.




回答3:


System.Array (the class representing an array) is a reference type and lives on the heap. You can only have an array on the stack if you use unsafe code.

I can't see where it says otherwise in the article that you refer to. If you want to have a stack allocated array, you can do something like this:

decimal* stackAllocatedDecimals = stackalloc decimal[4];

Personally I wouldn't bother- how much performance do you think you will gain by this approach?

This CodeProject article might be useful to you though.



来源:https://stackoverflow.com/questions/1123939/is-c-sharp-compiler-deciding-to-use-stackalloc-by-itself

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!