我是 C++ 新手
我正在阅读一个示例,偶然发现了这样的结构std::for_each,但不明白为什么在有标准 for(val v : array) 时需要它?
运行时测试
#include <array>
#include <iostream>
#include <chrono>
#include <android/log.h>
#include <thread>
#include <fstream>
#include <utility>
using namespace std;
using namespace std::chrono;
void testDeleteIt() {
std::vector<int> workers;
for (int i = 0; i < 1000000; ++i) {
workers.push_back(i);
}
int count = 0;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for (int &i : workers) {
count += i;
}
__android_log_print(ANDROID_LOG_ERROR, "HERE", "HERE ::: %s", std::to_string(count).c_str());
count = 0;
long long int duration = duration_cast<microseconds>(high_resolution_clock::now() - t1).count();
__android_log_print(ANDROID_LOG_ERROR, "TIME1", "TIME 1::: %s", std::to_string(duration).c_str());
high_resolution_clock::time_point t2 = high_resolution_clock::now();
std::for_each(workers.begin(), workers.end(), [&count](int &i) -> void {
count += i;
});
count = 0;
__android_log_print(ANDROID_LOG_ERROR, "HERE", "HERE ::: %s", std::to_string(count).c_str());
duration = duration_cast<microseconds>(high_resolution_clock::now() - t2).count();
__android_log_print(ANDROID_LOG_ERROR, "TIME2", "TIME 2 ::: %s", std::to_string(duration).c_str());
}
事实证明,标准循环的执行速度快了近 2 倍
TIME 1::: 10102
TIME 2 ::: 18459
再加std::for_each上 lambda 的麻烦
那么它的优势在哪里呢?
这很简单——
std::for_each它至少早在 10 年前就出现了。所以,是的,现在有一个标准。但你不是唯一一个问这个问题的人。但是有几个特点。
std::for_each有几个附加功能。std::for_each可以使用两个迭代器给定的任意范围。只能做begin-end的标准。std::for_each您可以为您的类型重载并使循环“更快” - 因为该函数将知道您的类型的内部。execution_policy。这意味着通过轻微的移动,您可以使其成为for_each“多线程”,并且容器的处理速度会更快。在答案中,您正在测试求和。然后使用
std::accumulate. 我怀疑在第一种情况下,编译器弄清楚了您到底在总结什么,并简单地将其替换为“系列之和”公式。Clang 确切地知道如何做。在这种情况下,比较两个循环的性能有点不正确。通常,存在标准算法(并且不仅如此)是为了避免每次手动编写已经以最佳方式编写的代码。如果我们说我们
std::for_each不需要它,那么我们可以成功地说不需要标准算法。毕竟,你总是可以为自己编写一个算法和一个替换标准算法的类……此外std::for_each,一个仿函数返回它的参数,它可以存储重要信息。您可以手动编写相同的内容,但使用标准算法通常更容易且更可靠(为了避免错误)。在您的具体示例中,我认为没有它更合适。ps 另外,集合上的 For-loop 出现的时间比这个算法晚。还有一件事...一个示例,您可以在不使用的情况下使用特定范围
std::for_each根据这个例子,很明显如果序列将由
10000元素组成,并且我们需要处理某种小范围,那么我们仍然需要遍历所有元素并每次检查条件,这要昂贵得多而不是std::for_each通过这个特定范围,因此只考虑这个范围