Разные проходы по коллекции в С++

195
12 июля 2018, 02:50

недавно заинтересовался вопросом, на тему того, какие из различных методов проходов через коллекцию наиболее эффективные и производительные, да и вообще когда и в какой ситуации лучше применять тот или иной метод? За основу возьмем std::vector.

...
std::vector<std::string> cities;
std::string rostov = "Ростов";
std::string omsk = "Омск";
cities.push_back(rostov);
cities.push_back(omsk);
...

1 Метод - самый примитивный

for (size_t i = 0; i < cities.size(); i++)
{
     std::cout << cities.at(i) << std::endl;
}

2 Метод - range for

for (const auto& city : cities)
{
    std::cout << city << std::endl;
}

3 Метод - iterators

for (auto it = cities.begin(); it != cities.end(); it++)
{
    std::cout << *it << std::endl;
}

4 Метод - лямбды

std::for_each(cities.begin(), cities.end(), [] (std::string &city)
{  
    std::cout << city << std::endl;
});

Для примера был приведен вектор с двумя элементами, хотелось бы чтобы была затронут разговор про большого объема контейнеры. А также хотелось бы услышать про то какой из вариантов лучше и почему, если в теле цикла производить не просто вывод его элементов(можно было бы сделать так std::copy(...)), а производить какого-либо рода вычисления над элементами. Заранее спасибо...

Answer 1

В первом методе не нужен доступ к элементу с проверкой (cities.at(i) ) лишнее, так как в цикле вы исключили выход за пределы границ. Просто выводить нужно cities[i], тогда он будет эффективным.

Эффективнее изначально не хранить лишные обьекты :

std::vector<std::string> cities;
cities.push_back("Ростов");
cities.push_back("Омск");

Второй вариант также эффективен, как и следующий вариант:

copy(cities.begin(), cities.end(), std::ostream_iterator<std::string>(std::cout, " "));

Самый плохой вариант это четвертый, поскольку std::for_each каждый раз вызывает лямбду и возвращает ее, котрая вам в принципе не нужна. И если вы пытаетесь пользоваться альгоритмом std::for_each, то сначала подумайте, нет ли более специализированного альгоритма типа того, что я привел?

READ ALSO
Выбор библиотеки для проекта

Выбор библиотеки для проекта

Требуется примерно определить графическу библиотеку на C++ для следующего проекта

172
Как сделать простое правило с помощью boost::spirit c++?

Как сделать простое правило с помощью boost::spirit c++?

Мне нужно, чтобы слова подходящие к правилу выводились на экранПравило - слова в которых есть 6 больших букв подряд(например: АНДРЕЙ, АНДРИАНА,...

187
При проверке clang-ом выдает ошибку [закрыт]

При проверке clang-ом выдает ошибку [закрыт]

Если включить вcpp файл QtWidgets, то при проверке синтаксе clang (clang_complete, vim) отметиться ошибка, при переходе по которой мы поподем в файл qglobal

179
Изъятие значения QspinBox из сигнала

Изъятие значения QspinBox из сигнала

Накануне делаю простенькое приложение, а именно график на кривые ЛиссажуПочти все сделал, но остаётся маленькая загвоздка

212