在生成大量数据然后处理该数据时遇到问题。
从概念上讲,我认为我会先创建一个程序来生成数据,然后再创建另一个程序来处理它,但是我担心将数据从一个程序推送到另一个程序的时间。
因此,我决定比较一下如果将这两个过程与在同一程序中同时包含数据生成和处理相比,将有多少开销。
下面的代码有点长,它要做的就是生成随机数据,然后将stdio::pipe
与std::memcpy
进行比较,以便将随机数据复制到另一个向量中。
但是,在管道+数据生成不仅比memcpy快,而且比单独的数据生成快的情况下,我得到的结果也没有意义。
我在误解什么?
数据生成:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
#include <vector>
#include <cstring>
#include <ctime>
#define BUFFER_SIZE 1000
#define MYDATA_SIZE 100000000 // ~400 MB
std::vector<int> makeData() {
std::srand(std::time(nullptr));
std::vector<int> data(MYDATA_SIZE);
std::generate(data.begin(), data.end(), std::rand);
return data;
}
int main() {
auto data = makeData();
fwrite(data.data(), 4, data.size(), stdout);
return 0;
}
// g++ -std=c++11 -O3 test2.cpp -o test2
数据处理:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
#include <vector>
#include <cstring>
#include <ctime>
#include <numeric>
#include <random>
#define BUFFER_SIZE 1000
#define MYDATA_SIZE 100000000 // ~400 MB
std::vector<int> makeData() {
std::srand(std::time(nullptr));
std::vector<int> data(MYDATA_SIZE);
std::generate(data.begin(), data.end(), std::rand);
return data;
}
std::vector<int> copyDataFromProcess(std::string cmd) {
std::vector<int> buffer(BUFFER_SIZE);
std::vector<int> result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
size_t bytes_read;
while ( (bytes_read = fread(buffer.data(), 4, buffer.size(), pipe.get())) ) {
result.insert(result.end(), buffer.begin(), buffer.begin() + bytes_read);
}
return result;
}
std::vector<int> copyDataFromInternal() {
std::vector<int> mydata = makeData();
std::vector<int> result(MYDATA_SIZE);
std::memcpy(result.data(), mydata.data(), MYDATA_SIZE);
return result;
}
int main() {
std::clock_t start;
start = std::clock();
auto ret1 = copyDataFromProcess("./test2");
std::cout << "Copy From Process: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
start = std::clock();
auto ret2 = copyDataFromInternal();
std::cout << "Copy From Internal: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
start = std::clock();
auto ret3 = makeData();
std::cout << "Make Data Time: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
std::cout << std::accumulate(ret1.begin(), ret1.end(), 0) << " " << ret1.size() << std::endl;
std::cout << std::accumulate(ret2.begin(), ret2.end(), 0) << " " << ret2.size() << std::endl;
std::cout << std::accumulate(ret3.begin(), ret3.end(), 0) << " " << ret3.size() << std::endl;
return 0;
}
// g++ -std=c++11 -O3 test.cpp -o test
结果:
Copy From Process: 718.696 ms
Copy From Internal: 1104.66 ms
Make Data Time: 868.188 ms
2092103051 100000000
-638719098 100000000
-1973221745 100000000