我有一个C ++结构,需要将其转换为列表,以便可以加载到GPU
struct point_cloud_tensor
{
std::vector<float> timestamp;
std::vector<std::vector<double>> position;
// more fields
};
point_cloud_tensor sweep_to_array(const point_sweep &point_sweep)
{
const auto num_points = point_sweep.points.size();
point_cloud_tensor tensor;
point_cloud_tensor.timestamp.reserve(num_points);
point_cloud_tensor.point.reserve(num_points);
for (int i = 0; i < point_sweep.points.size(); i++)
{
const auto point = point_sweep.points.at(i);
tensor.timestamp.push_back(point.timestamp);
std::vector<double> point_triple(3);
point_triple.push_back(point.x);
point_triple.push_back(point.y);
point_triple.push_back(point.z);
tensor.position.push_back(point_triple);
// more fields
}
return tensor;
}
扫描矢量中大约有10万个点,运行时间约为30毫秒。
有没有办法大幅度减少这种情况?
答案 0 :(得分:1)
在这种情况下,您的std::vector
用于小型阵列,为此,您可以将其替换为std:array
如前所述,测试代码的运行速度取决于硬件,因此我无法100%确定此更改是否会更快。
答案 1 :(得分:0)
由于您已经将point_sweep.points.size()
存储到变量num_points
中,因此可以在for
循环中使用它。当您这样迭代时:
for (int i = 0; i < point_sweep.points.size(); i++)
每次迭代时,您都将取消引用point_sweep
和取消引用points
以调用其方法size()
。改用局部变量应该更快:
for (int i = 0; i < num_points; i++)
获取观点时:
const auto point = point_sweep.points.at(i);
您无缘无故在调用复制构造函数。您应该使用对它的引用,使用&
:
const auto& point = point_sweep.points.at(i);
引用可能会有风险,因为您执行的每次修改都会应用于原始对象,但是由于您使用的是const reference
,因此应该是安全的。
填写tensor.position
向量后,您可以:
因此,此代码:
std::vector<double> point_triple(3);
point_triple.push_back(point.x);
point_triple.push_back(point.y);
point_triple.push_back(point.z);
tensor.position.push_back(point_triple);
成为:
tensor.position.push_back({point.x, point.y, point.z});
在我看来,它变得更容易阅读。
此外,正如其他人指出的那样,如果您可以更改数据结构,则可以使用std::array或std::tuple,也可以简单地编写诸如struct Point { double x, y, z; }
之类的结构。几乎可以像访问向量一样访问数组,这应该使转换更容易一些。该元组必须由std :: get访问,这需要重写一些代码。例如,如果要显示最后一个元素的内容:
struct point_cloud_tensor
{
std::vector<float> timestamp;
std::vector<std::tuple<double,double,double>> position;
// more fields
} tensor;
auto last_pos = tensor.position.back();
std::cout << "x=" << std::get<0>(last_pos) << ' ';
std::cout << "y=" << std::get<1>(last_pos) << ' ';
std::cout << "z=" << std::get<2>(last_pos) << std::endl;
但是,通过元组,您可以使用emplace_back而不是push_back添加项目,这样可以节省移动构造函数,例如:
tensor.position.emplace_back(point.x, point.y, point.z);
请注意语法上的差异。使用push_back,您有一个参数{point.x, point.y, point.z}
,但是使用emplace_back,您有3个参数point.x, point.y, point.z
。基本上,使用emplace_back只是删除花括号。
答案 2 :(得分:0)
您是否考虑过在构造点时退后一步并创建列表?