赞
踩
在C++编程中,经常会涉及两个容器之间的数据拷贝(如数组之间元素的拷贝),常规的做法一般都是用for循环逐个元素进行拷贝。在数据量不大的情况下还可以,如果数据量比较大,效率则会比较低下。
而 std::copy 就是一个专门用于容器间拷贝的函数,其效率是优于使用for循环的!但是需要注意的是:std::copy 只负责复制,不负责申请空间,所以复制前必须有足够的空间。
而 std::copy_if,则是在 std::copy 执行的时候,可以让你有机会对源容器的元素进行判断,从而决定哪些元素可以拷贝,哪些不拷贝!
在实验之前,我们先了解一下 iota 这个函数(iota 可用于生成连续的数字序列)
#include <iostream>
#include <numeric>//std::iota
int main()
{
int numbers[10];
int startVal = 100;//start value
std::iota(numbers, numbers + 10, startVal);
std::cout << "Elements are:";
for (auto i : numbers)
std::cout << ' ' << i;
std::cout << '\n';
}
输出结果:
Elements are: 100 101 102 103 104 105 106 107 108 109
#include <iostream> #include <numeric>//std::iota #include <vector> #include <algorithm> int main() { //iota 可用于生成连续的数字序列 std::vector<int> fromVector(10); std::iota(fromVector.begin(), fromVector.end(), 0); // std::vector<int> toVector; std::copy(fromVector.begin(), fromVector.end(), std::back_inserter(toVector)); #if 0 // 或者 std::vector<int> toVector(fromVector.size()); std::copy(fromVector.begin(), fromVector.end(), toVector.begin()); // 无论哪种方式,实际结果都相当于 std::vector<int> toVector = fromVector; #endif std::cout << "toVector contains: "; std::copy(toVector.begin(), toVector.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; //把fromVector中偶数拷贝到toVector std::cout << "even numbers in toVector are: "; std::copy_if(toVector.begin(), toVector.end(), std::ostream_iterator<int>(std::cout, " "), [](int x) { return std::fmod(x, 2) == 0; }); std::cout << '\n'; //把fromVector中是3的倍数拷贝到toVector std::cout << "toVector contains these multiples of 3:\n"; toVector.clear(); std::copy_if(fromVector.begin(), fromVector.end(), std::back_inserter(toVector), [](int x) { return std::fmod(x, 3) == 0; }); for (int x : toVector) std::cout << x << ' '; std::cout << '\n'; return 0; }
输出结果:
toVector contains: 0 1 2 3 4 5 6 7 8 9
even numbers in toVector are: 0 2 4 6 8
toVector contains these multiples of 3:
0 3 6 9
#include <iostream> #include <numeric>//std::iota #include <vector> #include <algorithm> #include <chrono> class timelapsed { public: timelapsed(std::string&& name) : m_name(std::forward<std::string>(name)) , m_now(std::chrono::high_resolution_clock::now()) { } ~timelapsed() { auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> dur(end - m_now); std::cout << m_name << " : " << dur.count() << " seconds ##### \n"; } private: std::string m_name; std::chrono::time_point<std::chrono::high_resolution_clock> m_now; }; int main() { int container_size = 1000000; std::vector<int> vectorFrom(container_size); std::iota(fromVector.begin(), fromVector.end(), 0); int* vectorTo = new int[vectorFrom.size()]; { timelapsed _timelapsed("use copy"); std::copy(vectorFrom.begin(), vectorFrom.end(), vectorTo); } { timelapsed _timelapsed("use for"); for (int i = 0; i < container_size; i++) { vectorTo[i] = vectorFrom[i]; } } return 0; }
性能测试结果:
use copy : 0.0001559 seconds #####
use for : 0.0108972 seconds #####
可以看到,在拷贝大数据量时,std:copy 的效率是远高于使用 for 循环的!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。