Какой самый эффективный способ реализовать таблицу, которая хранит разреженные данные в C # - PullRequest
2 голосов
/ 22 июля 2010

У меня есть DataTable, в котором хранятся очень разреженные данные, например:

   P1 P2 P3 P4 P5 ...
J1 1  1
J2    1  1
J3             1
.
.
.

Количество строк и столбцов может превышать 10 ^ 8.

Как я могу сохранить эти данныеболее эффективным способом?

Ответы [ 3 ]

1 голос
/ 22 июля 2010

Если файловая система вашего диска поддерживает Разреженные файлы , вы можете создать пустой файл, пометить его как разреженный, а затем изменить его размер на rows * colums * datasize.

Тогда вам нужно получить доступ кданные по [row] [column], где смещение может быть вычислено с помощью:

offset = ((columns.length * (row-1)) + column) * datasize

Существуют некоторые издержки с разреженными файлами, а также в отношении размещения, где обычно выделяются страницы размером 16-64 КБ, но в зависимости откак ваши кластеры данных это может очень хорошо работать.

0 голосов
/ 08 июля 2012

Существует много предшествующего уровня техники для эффективного хранения запасных матриц.

Общий подход известен как "Список списков".Например, в Python есть эффективный способ хранения запасных матриц в виде ' разбросанной матрицы списочного списка на основе строк '.

0 голосов
/ 22 июля 2010

Во-первых, избавьтесь от DataTable для этих подсчетов данных. Использование памяти здесь очень велико.

Если ваши данные всегда равны 0/1, наиболее эффективным способом должна быть битовая маска.

Если ваши данные не только 0/1, создайте структуру, которая абстрагирует все ваши столбцы.

Вот концептуальный прототип этой структуры данных.

class MyData {
    public MyData(int[] columns, object[] data) {
        _columns = columns;
        _data = data;
    }

    int[] _columns;
    object[] _data;

    public object this[int column] {
        get {
            int index = IndexOf(column);
            return index != -1 ? _data[index] : null;
        }
    }

    private int IndexOf(int column) {
        for (int i = 0; i < _columns.Length; i++)
            if (_columns[i] == column)
                return i;
        return -1;
    }
}

Вы можете дополнительно сохранить память для _columns, применив шаблон flyweight.

Надеюсь, это поможет

...