Я новичок в boost.python и сделал простую функцию для передачи списка из Python в вектор C ++:
void SetXValues(boost::python::list xl){
int n = len((xl));
xvals.resize(n);
for(unsigned int i=0; i<n; i++){
xvals[i] = boost::python::extract<double>((xl)[i]);
}
}
xvals — это вектор C ++ STL. Эта функция работает, и я могу загрузить список Python в C ++, но он кажется очень медленным.
Небольшой тест скорости я сделал, чтобы написать алгоритм биннинга на C ++ и на чистом Python. Результаты показывают, что метод C ++ работает только в 5 раз быстрее, когда включено время для передачи данных из Python, но, конечно, один алгоритм биннинга значительно быстрее (74x).
Так есть ли способ улучшить вышеуказанную функцию, чтобы сделать ее более эффективной?
В критических частях производительности, таких как вы описываете. Я обычно избегаю хранить данные в питоне list
на первом месте. list
правильный тип данных для хранения в нем произвольных объектов. В частности, каждый объект в списке может иметь различный тип. Но вы уже знаете, что это будет «список двойников».
Я бы рекомендовал вместо этого использовать std::vector<double>
уже в питоне. Для этого вы бы экспортировали std::vector<double>
как class_
Давайте назовем это VectorOfDOubles
, используя boost python. Вы можете сделать это так, что в Python вы не увидите разницу между list
а также VectorOfDoubles
с основным отличием в том, что вы создаете его как xl = VectorOfDoubles(55)
вместо xl = []
, Вам понадобится немного работы, чтобы заставить работать индексные тузы, например, xl [5] = 4.5, но для этого существует пакет повышения индексации, я рекомендую версию 2, чтобы помочь вам.
Другой альтернативой было бы использовать numy ndarrays вместо list
, Существует библиотека boost numpy, которая помогает вам работать с numpy ndarrays из boost python.
Но, как вы говорите, вы новичок в улучшении Python, и пакет Boost Numpy и Boost Indexing Suite могут быть довольно сложными. Может быть, вы сначала хотите сделать свой собственный подкласс std::vector<double>
, сказать VectorOfDOubles
и определить double get(int i)
а также void set(int i, double val)
и затем экспортируйте эти две функции (вместе с size (), конструктором) в python. Это требует некоторых изменений в вашем коде Python, но это проще для начинающих.
Других решений пока нет …