c++ – What is the difference between foreach and std :: for_each in C ++?

Question:

I am new to C ++

I am reading an example and came across such a construction std::for_each and did not understand why it is needed when there is a standard for (val v: array)?

Tested for runtime

#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());
}

And it turned out that the standard cycle is executed almost 2 times faster

TIME 1::: 10102
TIME 2 ::: 18459

And plus in std::for_each there are also problems with lambda

So what is its advantage then?

Answer:

I am reading an example and came across such a construction std :: for_each and did not understand why it is needed when there is a standard for (val v: array)?

It's simple – std::for_each appeared at least 10 years earlier. Therefore, yes, there is now a standard for. But you are not the only one who asks such a question .

But there are several peculiarities. std::for_each has several additional features.

  • std::for_each can work with an arbitrary range given by two iterators. The standard for only knows how to begin-end.
  • std::for_each can be overloaded for your type and make the loop "faster" – because the function will know the insides of your type.
  • And at 17, the execution_policy brought up. This means that with a slight movement you can make for_each "multithreaded" and the container will be processed much faster.

In the answer, you are testing summation. Then use std::accumulate . I have a suspicion that in the first case, the compiler figured out what you are summing up and simply replaced it with the "sum of the series" formula. Clang does just that. In this case, it is a little incorrect to compare the performance of the two loops.

Scroll to Top