c++ - 如何从 C++11 中的 std::future 移动结果?
问题描述
我想std::vector<int>
在我的程序中异步处理 a 。然而,对象的检索不使用移动语义。
我创建了一个最小的工作示例并将其附在下面。根据cplusplus.com,复制和构造向量的移动语义在被移动对象的大小上是线性的,在被移动对象的大小上是恒定的,只要它们共享相同的分配器(我正在使用标准一)。再次根据cplusplus.comstd::future<T>::get()
的说法,当从and T
is void
not 也不是引用类型(不是这种情况)中检索对象时,它的行为就像移动值一样。
我什至尝试只inputs[i].get();
在第二个循环中使用,目前在评论中,而不是将其分配给任何东西。这仍然给线性时间增加。
std::vector<std::vector<int>> GenerateTestCases(int input_size, int number_inputs) {
std::vector<std::vector<int>> cases(number_inputs);
for (auto i = 0; i < number_inputs; i++) {
std::vector<int> some_vector(input_size);
cases[i] = std::move(some_vector);
}
return std::move(cases);
}
int main() {
for (auto i = 0; i < 25; i++) {
auto size = (int)pow(2, i);
int iterations = 100;
auto test_cases = GenerateTestCases(size, iterations);
std::vector<std::future<std::vector<int>>> inputs(iterations);
const auto start = std::chrono::high_resolution_clock::now();
for (auto i = 0; i < test_cases.size(); i++) {
std::promise<std::vector<int>> prom;
prom.set_value(std::move(test_cases[i]));
inputs[i] = std::move(prom.get_future());
}
const auto middle = std::chrono::high_resolution_clock::now();
for (auto i = 0; i < test_cases.size(); i++) {
//inputs[i].get();
auto& result = (inputs[i]);
auto value = std::move(result.get());
}
const auto end = std::chrono::high_resolution_clock::now();
const auto elapsed_first = std::chrono::duration_cast<std::chrono::nanoseconds>
(middle - start).count();
const auto elapsed_second = std::chrono::duration_cast<std::chrono::nanoseconds>
(end - middle).count();
std::cout << "First: " << elapsed_first << std::endl;
std::cout << "Second: " << elapsed_second << std::endl;
std::cout << std::endl;
}
char c;
std::cin >> c;
}
但是,当我执行上面的代码时,我看到执行时间线性增加,范围从
第一个:13440ns 第二个:9919ns
对于最小的数组大小
第一个:25919ns 第二个:300147450ns
对于最大的一个。
我在 Win10 上使用 VS2019 并为 x64 编译,如果这是出于兴趣的话。
解决方案
时间成本可能来自向量的破坏。
我做了一个测试,当结果保存在另一个向量中时时间不会增加(即防止破坏)
http://coliru.stacked-crooked.com/a/dc7792496a981de3
在您的原始代码中,时间确实增加了
推荐阅读
- html - CSS中的伪焦点不适用于所有对象
- reactjs - 错误是传播不可迭代实例的无效尝试。为了可迭代,非数组对象必须有一个 [Symbol.iterator]() 方法
- android - 如何更改TextInputLayout内edittext的边框颜色
- javascript - 如果时间少于所选时间,如何在议程周中更改颜色
- python - 在列表中搜索 - 是否有更有效的方法来编写此代码?
- javascript - IoT 设备上的 HTTPS 握手失败
- prometheus - 用普罗米修斯计算最大值
- node.js - NodeJS 中的图片上传
- ruby - jekyll 构建错误未知编码名称“chunked\r\n\r\n25”
- macos - 如何删除一直自行打开的mac应用