Хранение неиспользуемых членов данных класса на диске - PullRequest
0 голосов
/ 22 марта 2012

У меня есть приложение с графическим интерфейсом, которое работает с данными облака точек и структурой данных квадродерева позади него для обработки данных.Поскольку формат точек, с которыми я работаю, недавно изменился, мне пришлось изменить класс точек, чтобы он содержал новые атрибуты, которые приводят к значительному увеличению размеров объектов Point и, в результате, к снижению производительности моего дерева квадрантов.Некоторые из этих атрибутов не нужны для отображения и обработки данных, но их все же необходимо сохранить в выходных данных.Примерно так выглядит мой класс точек:

class Point {
public:
    /* ... */
private:
    /* Used data members */
    double x;
    double y;
    double z;
    double time;
    int attr1;
    int attr2;

    /* Unused data members */
    int atr3;
    double atr4;
    float atr5;
    float atr6;
    float atr7;
}

Когда данные загружаются из файла, точки сохраняются в массиве Point *, а затем обрабатываются квадродеревом.Точно так же, когда они сохраняются, массив точек передается из дерева квадрантов и сохраняется в файл.Обратите внимание, что объекты Point, которые я использую в своем дереве quadtree, отличаются от тех, которые хранятся в файле, но я использую библиотеку, которая предоставляет объекты для чтения и записи, которые я использую для создания своих точек.Вот пример:

int PointLoader::load(int n, Point* points) {

    Point temp;
    int pointCounter = 0;

    /* reader object is provided by the library and declared elsewhere */        
    while (pointCounter < n && reader->read_point()) {
        temp = Point(reader->get_x(), reader->get_y(), reader->get_z(), /* ... */ )

        points[pointCounter] = temp;
        ++pointCounter;        
    }
    return pointCounter;
}

Теперь моя идея состоит в том, чтобы уменьшить размер класса Point и сохранить неиспользуемые атрибуты в другом классе (или структуре) под названием PointData на жестком диске.Это необходимо, потому что данные обычно не помещаются в память и на них установлена ​​система кеширования, которая снова выиграет от более мелких точечных объектов.Поэтому, учитывая пример, это выглядело бы примерно так:

int PointLoader::load(int n, Point* points) {

    Point temp;
    PointData tempData;
    int pointCounter = 0;    

    while (pointCounter < n && reader->read_point()) {
        temp = Point(reader->get_x(), reader->get_y(), reader->get_z(), /* ... */ )
        pointData = (reader->get_attr3(), reader->get_attr4(), /* ... */)

        temp.dataHandle = /* some kind of handle to the data object */
        points[pointCounter] = temp;

        /* Save pointData to file to retrieve when saving points */

        ++pointCounter;        
    }
    return pointCounter;
}

Тогда, когда я сохранял свои измененные точки, я просто использовал dataHandle (смещение файла? Индекс в массиве с отображенной памятью?), Чтобы извлечь pointDataкаждой точки и запишите его обратно в файл.

Это звучит как хорошая идея?Каков наиболее разумный подход для достижения этой цели?

1 Ответ

1 голос
/ 22 марта 2012

Я бы посоветовал вам использовать сопоставленные файлы для хранения дополнительных данных.Это автоматически приведет к тому, что они будут сброшены на диск и удалены из ОЗУ, если имеется нагрузка на память, но они будут оставаться в ОЗУ большую часть времени, если будет достаточно памяти.

В вашем классе Point,Хранить смещения в файле лучше, чем сохранять прямые указатели в отображаемой области памяти, поскольку смещения все равно будут правильными, если вам потребуется переназначить файл для его увеличения (вы должны увеличивать файл, используя, например, lseek() самостоятельно, так как выможет отображать только размер файла).

Этот механизм очень удобен для кодирования, но у вас должно быть достаточно адресного пространства для сопоставления всего файла - без проблем в 64-разрядном приложении,но, возможно, проблема, если вы 32-битный и вам требуется больше, чем несколько сотен МБ данных в файле.Конечно, вы можете отображать и удалять несколько файлов, но это требует больше работы по написанию кода и является менее производительным (есть некоторые затраты на отображение и удаление файлов).

...