Предположим, у нас есть внешняя библиотека, которая может очень быстро выполнять вычисления (в большинстве случаев многопоточные) на массиве чисел с плавающей запятой двойной точности. Для удобства я пишу свой код объектно-ориентированным способом, чтобы получить массив объектов. Каждый объект имеет свойство, содержащее двойное значение. Наивный подход к использованию мощной внешней библиотеки выглядит примерно так:
double temp[N];
for i from 1 to N
temp[i] = objectArray[i].property;
end
Тем не менее, для удержания температура массив. Есть ли лучший способ сделать это?
Это общий вопрос, но я в основном хочу этого в C ++.
Если вы уверены, что ваши объекты содержат только double
элемент данных, нет оснований для добавления элементов данных и нет virtual
функции — проверьте со статическим утверждением, что sizeof(*objectArray) == sizeof(double)
— и предполагая, что ваша функция внешней библиотеки находится вне очереди, вы можете просто передать внешнюю библиотеку double*
в objectArray[0]
,
Если функция библиотеки встроена в заголовок, который вы включаете, вы можете столкнуться с проблемами псевдонимов и должны проконсультироваться с вашими документами компилятора для вариантов.
Если твой objectArray
элементы не просто держи double
каждый, ты будут нужно скопировать их в сжатый массив, если этого ожидает внешняя библиотека. (Одним из вариантов, который вы могли бы рассмотреть, является сохранение double
значения в массиве, и ваши более сложные объекты хранят ссылки на элементы массива).
Вы можете использовать стратегию арены для своих объектов. По сути, наш объект будет содержать только индекс и дескриптор области данных. Фактические данные хранятся на арене под правильным индексом. Таким образом, когда вам нужно создать вектор double, он уже существует внутри арены.
Это работает, только если вы всегда знаете, какие объекты обрабатываются вместе, и они почти всегда обрабатываются вместе. Если вам нужно каждый раз выбирать, какие объекты вам нужны, это не даст вам никакого увеличения производительности (если только объекты не всегда соприкасаются в массивах). Это также делает обычный доступ к объектам немного медленнее, поэтому имеет смысл, только если копирование значений каждый раз действительно является узким местом в вашей программе.
Ваши структуры данных будут выглядеть так:
class Arena {
vector<double> propertyX;
vector<double> propertyY;
int next_index;
};
class MyObject {
int index;
Arena& arena
MyObject(Arena& arena_ref): arena(arena_ref) { index = arena.next_index++; }
double getX() { return arena.propertyX[index]; }
};
Вам нужно немного больше кода, чтобы убедиться, что вещи распределены и тому подобное, но вы поняли идею. Теперь, когда вам нужно вызвать внешнюю библиотеку, вы получаете массивы непосредственно из Arena
объект.