我正在努力实现一个代码,这是写在MATLAB到C++。
在MATLAB中,你可以用另一个数组来切片一个数组,比如A(B),这会导致A的元素在B中的元素值指定的索引处的一个新数组。
我想在C++中使用vector做类似的事情。这些vector的大小为10000-40000个double类型的元素。
我希望能够使用另一个int类型的vector来切片这些vector,其中包含要切片的索引。
例如,我有一个向量v = <1.0,3.0,5.0,2.0,8.0>和一个向量w = <0,3,2>。我想使用w对v进行切片,使得切片的结果是一个新的向量(因为旧的向量必须保持不变)x = <1.0,2.0,5.0>。
我想了一个函数来做这个:
template<typename T>
std::vector<T> slice(std::vector<T>& v, std::vector<int>& id) {
std::vector<T> tmp;
tmp.reserve(id.size());
for (auto& i : id) {
tmp.emplace_back(v[i]);
}
return tmp;
}
字符串
我想知道是否有可能更有效的方法来完成这样的任务。速度是这里的关键,因为这个切片函数将在一个大约300000次迭代的for循环中。我听说boost库可能包含一些有效的解决方案,但我还没有使用它的经验。
我使用了chrono库来测量调用这个slice函数所花费的时间,其中要切片的vector的长度为37520,包含索引的vector的大小为1550。对于这个函数的单次调用,所花费的时间= 0.0004284 s。然而,超过300000次for循环迭代,总花费的时间是134 s。
任何建议将非常感谢!
3条答案
按热度按时间ds97pgxw1#
emplace_back
有一些开销,因为它涉及std::vector
内部的一些内部会计。请尝试以下操作:字符串
此外,我删除了你的内部循环中不必要的解引用。
**编辑:**我又想了想,受到@jack的回答的启发,我认为内部循环(这是最重要的一个)可以进一步优化。这个想法是把循环使用的所有东西放在局部变量中,这给了编译器优化代码的最佳机会。所以试试这个,看看你得到了什么样的时间。确保你测试了一个发布/优化的构建:
型
xxslljrj2#
性能似乎有点慢;你是用编译器优化构建的(例如
g++ main.cpp -O3
,或者如果使用IDE,切换到发布模式)。仅这一点就将计算时间加快了10倍左右。如果你已经在使用优化了,通过使用基本的for循环迭代,
(for int i = 0; i < id.size(); i++)
的计算时间在我的机器上加快了2- 3倍,这个想法是,编译器不必解析auto
引用的类型,而且由于基本的for循环一直在C++中,编译器可能有很多技巧来加速它。字符串
bksxznpy3#
我想在C中使用vector做类似的事情。
C对Matlab的可切片向量的回答不是
std::vector
;而是std::valarray
。https://en.cppreference.com/w/cpp/numeric/valarray
C的
std::valarray
支持在std::slice
的帮助下示例化其他std::valarray
对象。一旦你有了valarray slice对象,C的
std::valarray
显式地支持对它的每个元素应用标量操作,不仅是基本的算术操作,而且还通过将函数传递给std::valarray::apply
来对它的每个元素应用函数。