2016-04-26 2 views
1

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

double temp[N]; 
for i from 1 to N 
    temp[i] = objectArray[i].property; 
end 

Однако, это требует времени и дополнительной памяти для хранения Темп массива. Есть ли лучший способ сделать это?

Это общий вопрос, но я в основном хочу этого в C++.

+1

Если ваша библиотека выполняет алгоритм на массиве и _only_ массив, то это единственный способ. Если ваша библиотека может выполнить ее по-другому, нам нужно будет немного узнать об этой библиотеке. – Unda

+0

Есть несколько вариантов, о которых я могу думать: 1. Удерживайте двойного [] члена рядом с вами objectArray и убедитесь, что они всегда синхронизированы. 2. Лучше всего заменить двойное свойство двойным *, указывающим на double []. Это избавит вас от написания кода синхронизации –

+0

Не зная библиотеки 'API', трудно найти предложения. Вот почему стиль интерфейса STL настолько силен, что они обобщили концепцию указателей как * итераторов *. Если ваша библиотека должна была принимать * итераторы *, это было бы намного проще. Есть ли что-то подобное в «API»? – Galik

ответ

2

Если вы уверены, что ваши объекты содержат только элемент в double данных, данные членов-добавляющие основ и нет virtual функции - проверьте со статическим утверждением, что sizeof(*objectArray) == sizeof(double) - и предполагается, что ваша внешняя библиотечной функция вне-линии , вы можете просто передать внешнюю библиотеку double* в objectArray[0].

Если встроенная функция библиотеки включена в заголовок, который вы включаете, вы можете столкнуться с проблемами сглаживания и обратиться к своим документам компилятора для параметров.

Если objectArray элементы не просто провести double каждый, вы будет должны скопировать их в уплотненном массив, если это то, что внешняя библиотека ожидает. (Один из вариантов, который вы можете рассмотреть, заключается в сохранении значений double в массиве, а наличие более сложных объектов хранит ссылки на элементы массива).

+0

Мой 'objectArray' также содержит другие базовые типы данных и объекты других классов через композиции. Что значит компактный массив? Итак, вы рекомендуете хранить этот двойной массив в свойстве класса? –

+0

@ ZoltánCsáti: «compacted array» Я просто подчеркивал элемент-смежный в памяти аспект массива. Если вы создаете массив таким образом, чтобы библиотека могла быть применена к нему, а затем извлекая элементы обратно в элементы 'objectArray', нет никакого очевидного значения в *" хранении этого двойного массива в свойстве класса "*. Если вы обнаружите, что хотите обрабатывать массив как объект и вызывать операции над ним, то вы можете потрудиться, чтобы создать класс хранения или управления массивом. Извините, если это не поможет - это баланс потребностей, который определяет лучший выбор. –

+0

«Если вы создаете массив, чтобы к нему можно было применить библиотеку». Да, это только то, что мне нужно. Поэтому, если я это хорошо понимаю, вы говорите: 0) не храните этот двойной массив в свойстве - он не нужен, 2), поскольку я не хочу делать какие-либо операции над этим массивом (просто нужно передать его к существующей библиотеке), используйте мой наивный подход, увиденный в моем вопросе. –

1

Вы можете использовать стратегию арены для своих объектов. В основном наш объект будет содержать только индекс и дескриптор области данных. Фактические данные хранятся на арене по правому индексу. Таким образом, когда вам нужно создать вектор 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.

Смежные вопросы