0

I have the following code and for some reason the ToArray() method takes 7ms for a single element. The application has several worker threads in which this happens and I have also profiled the application with JetBrains dotTrace which shows that the thread is waiting for another one in this time (and not just waiting for the CPU), which should obviously not be possible because the List is a local variable and I don't use locks.

List<TransactionType> transactionTypes = 
   new List<TransactionType>(_TransactionTypes.LengthNull() + 
   drawingAction._TransactionTypes.LengthNull())
...
Stopwatch sw = Stopwatch.StartNew();
_TransactionTypes = transactionTypes.ToArray();
sw.Stop();
if (sw.ElapsedMilliseconds > 3)
{
  int deb = 0;
}

This phenomenon occurs pretty much at every point where methods of the .Net framework are used (e.g. String.Format). I had this problem for a while now and for some reason using a SpinWait in the main thread makes it even worse.

Neither I nor my colleagues have an explanation for this and Google didn't help either so I'd by very thankful for help.

Found the problem:
Or at least a part of it. It seems like it was caused by GC pressure and I already know how to reduce it in the application. I have still no clue why SpinWait sometimes caused the blocking of threads but I resorted to just not using it.

This question was marked as a duplicate and Stack Overflow told me to edit it to explain why but to be honest it is pretty damn clear that it isn't if you even bother to read past the title.

  • Write up a basic implementation of `ToArray` and put your diagnostic `Stopwatch` checks into it. If you find that it's the buffer array allocation that takes up the bulk of the execution time, that points to GC pressure or possibly overall system load issues. You can use [the actual ToList method source](https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,d4409b7542728cec) as your starting point, and further increase granularity by replacing `Array.Copy` with a `for` loop if needed. – Kirill Shlenskiy Mar 25 '18 at 11:44
  • I reopened this question because it's clearly not a duplicate of https://stackoverflow.com/questions/1147497/c-sharp-listt-toarray-performance-is-bad (which merely asks, "I heard that ToArray is slow; is that true?") – Michael Liu Apr 02 '18 at 18:00

1 Answers1

0

I've just looked into the .NET source code. So apparently it just copies the current content of the lists array into a new array.

T[] array = new T[_size];
Array.Copy(_items, 0, array, 0, _size);   //_items is the lists inner array     
return array;

Nothing more to it than just copying.

Lucas Engleder
  • 661
  • 1
  • 6
  • 18
  • Yeah I know, that's why I'm so confused. – Niklas Hauber Mar 25 '18 at 12:30
  • I've found the same question already on stackoverflow. [link](https://stackoverflow.com/questions/1147497/c-sharp-listt-toarray-performance-is-bad) Pay attention to the answer where someone says that adding the first element to the list the capacity increases to 16 – Lucas Engleder Mar 27 '18 at 11:20