Учитывая этот простой фрагмент кода и 10 миллионов массивов случайных чисел:
static int Main(string[] args)
{
int size = 10000000;
int num = 10; //increase num to reduce number of buckets
int numOfBuckets = size/num;
int[] ar = new int[size];
Random r = new Random(); //initialize with randum numbers
for (int i = 0; i < size; i++)
ar[i] = r.Next(size);
var s = new Stopwatch();
s.Start();
var group = ar.GroupBy(i => i / num);
var l = group.Count();
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
Console.ReadLine();
return 0;
}
Я сделал некоторую производительность при группировке, поэтому, когда количество ведер составляет 10 тыс., расчетное время выполнения составляет 0,7 с, для 100 тыс. ведер - 2 с, для 1 м - 7,5 с.
Интересно, почему. Я предполагаю, что если GroupBy реализован с использованием HashTable, может возникнуть проблема с коллизиями. Например, изначально хеш-таблица готовится к работе, чтобы сказать 1000 групп, а затем, когда число групп растет, необходимо увеличить размер и выполнить повторную запись. Если бы это было так, я мог бы написать свою собственную группу, где я бы инициализировал HashTable с ожидаемым количеством ведер, я сделал это, но это было только немного быстрее.
Итак, мой вопрос: почему количество ведер сильно влияет на производительность GroupBy?
EDIT: работающий под режимом освобождения, меняет результаты на 0,55, 1,6, 6,5 с соответственно.
Я также сменил группу. ToArray на фрагмент кода ниже, чтобы принудительно выполнить группировку:
foreach (var g in group)
array[g.Key] = 1;
где массив инициализируется перед таймером с соответствующим размером, результаты остались почти такими же.
EDIT2: Вы можете увидеть рабочий код из mellamokb здесь pastebin.com/tJUYUhGL