I'm working on a piece of code in C# / XNA where I'm highly concerned with performance. Part of this is passing several structs that are stored in arrays to various functions.
Before this is asked, these are indeed supposed to be structs, not classes. They're essentially value types, and they need to (basically) live on the stack. There are many of them, they come and go very quickly, and getting the garbage collector involved for them (even if I were running pools) would be expensive.
I've already improved performance quite a bit by passing by reference, but I'm wondering what the performance implications of that is when the same struct at the same index of an array is passed to several different functions by reference. I assume that in order for this to all work, C# has to internally pin the array pointer before passing the struct. Would I gain performance by pinning the struct first and passing the pointer instead?
For example. If I have something like:
for(int i = 0; i < array.Length; ++i)
{
value = Function1(ref array[i]);
// Lots of code....
otherValue = Function2(ref array[i]);
// Lots of code....
anotherValue = Function3(ref array[i]);
}
Doesn't C# essentially have to do this?
for(int i = 0; i < array.Length; ++i)
{
pin(array);
value = Function1(ref array[i]);
unpin(array);
// Lots of code....
pin(array);
otherValue = Function2(ref array[i]);
unpin(array);
// Lots of code....
pin(array);
anotherValue = Function3(ref array[i]);
unpin(array);
}
And would I be better off doing this?
for(int i = 0; i < array.Length; ++i)
{
fixed(struct* working = ^array[i])
{
value = Function1(working);
// Lots of code....
otherValue = Function2(working);
// Lots of code....
anotherValue = Function3(working);
}
}
Or, even better,
fixed(struct* working = ^array[0])
{
for(int i = 0; i < array.Length; ++i)
{
value = Function1(working[i]);
// Lots of code....
otherValue = Function2(working[i]);
// Lots of code....
anotherValue = Function3(working[i]);
}
}
Or is the C# compiler / JITter smart enough to automatically pin the array?