ConcurrentDictionary Эффективность памяти - PullRequest
0 голосов
/ 09 мая 2018

Для сравнения: я реализую алгоритм KMeans, используя набор данных netflix в C #.

Набор данных имеет такую ​​форму:

8: // This is the movie id
23414, 3, 16/5/2009 //User id, rate, date

Я храню данные как разреженные точки в следующих структурах данных:

struct Point {
    double Norm {get; set;} // Vector norm
    ConcurrentDictionary<ushort, double> Values; // {movie:rate, ...}

    void CalculateNorm() { ... }
}
public class KMeans {
    ...
    Point[] _dataset = new Point[470758];
    ...
}

Проблема в том, что после загрузки набора данных занимает 4 ГБ в ОЗУ, я запускаю сборщик мусора вручную, и это уменьшает использование памяти до половины (2 ГБ), но я ищу более оптимальное использование оперативной памяти, так как я решил это в C ++, и набор данных был только 500 МБ в ОЗУ.

Может кто-нибудь дать мне совет по этому поводу? Я оставил ссылку на репо, если вы хотите увидеть полный код: https://github.com/joalcava/Kmeans-CS/blob/master/Kmeans/KMeans.cs

1 Ответ

0 голосов
/ 09 мая 2018

Каждый словарь имеет тенденцию связываться с ним: несколько int с и некоторые ссылки на объекты, даже если он пуст, а затем вдвое больше места, чем нужно, когда вы начинаете добавлять элементы. Я полагаю, что ConcurrentDictionary почти такой же.

Таким образом, вместо того, чтобы помещать новый ConcurrentDictionary в каждую отдельную точку, вы можете попробовать использовать один ConcurrentDictionary, который отключен как от индекса массива точек, так и от ключа, который вы используете в данный момент. Новый синтаксис кортежа в C # 7 должен сделать это довольно легко.

...