Три (основных) подхода
Хорошо, в итоге я сделал три (основные) реализации (с небольшими вариациями).Я сделал простой тест, чтобы увидеть, есть ли различия в эффективности.Проверьте раздел тестов внизу
1.std::for_each
с лямбдой c ++ 0x
Использование некоторых сочетаний клавиш c ++ 0x: см. http://ideone.com/TvJZd
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> a = { 1,2,3,4,5,6,7 };
int sum=0, product=1;
std::for_each(a.begin(), a.end(), [&] (int i) { sum+=i; product*=i; });
std::cout << "sum: " << sum << ", product: " << product << std::endl;
return 0;
}
Печать
sum: 28, product: 5040
Как уже упоминалось другимиобычно вы предпочитаете нормальный цикл:
for (int i: a)
{ sum+=i; product*=i; }
Что на
- короче,
- более разборчиво,
- менее неожиданно(ref-capturing) и
- , вероятно, более оптимизируемый компилятором
Кроме того, очень близко в non-c ++ 11 / 0x:
for (std::vector<int>::const_iterator it=a.begin(); it!=a.end(); ++it)
{ sum+=*it; product*=*it; }
2,std::accumulate
с рукописным объектом-аккумулятором
Добавлен объект на основе std::accumulate
: см. http://ideone.com/gfi2C
struct accu_t
{
int sum, product;
static accu_t& handle(accu_t& a, int i)
{
a.sum+=i;
a.product*=i;
return a;
}
} accum = { 0, 1 };
accum = std::accumulate(a.begin(), a.end(), accum, &accu_t::handle);
3.std::accumulate
с std::tuple
Хорошо, я не удержался.Вот пример с accumulate
, но работающий с std::tuple
(устраняя необходимость в типе функтора): см. http://ideone.com/zHbUh
template <typename Tuple, typename T>
Tuple handle(Tuple t, T v)
{
std::get<0>(t) += v;
std::get<1>(t) *= v;
return t;
}
int main()
{
std::vector<int> a = { 1,2,3,4,5,6,7 };
for (auto i=1ul << 31; i;)
{
auto accum = std::make_tuple(0,1);
accum = std::accumulate(a.begin(), a.end(), accum, handle<decltype(accum), int>);
if (!--i)
std::cout << "sum: " << std::get<0>(accum) << ", product: " << std::get<1>(accum) << std::endl;
}
return 0;
}
Тесты:
Измеряется путем накопления2 << 31 раз (см. Фрагмент для варианта на основе std :: tuple).Протестировано только с -O2 и -O3: </p>
нет измеримых различий между любым из показанных подходов (0,760 с):
все варианты демонстрируют увеличение скорости более чем в 18 раз при переходе от -O2 к-O3 (от 13,8 до 0,760 с), опять же, независимо от выбранной реализации
tuple
/ accumulate
производительность остается неизменной с Tuple& handle(Tuple& t, T v)
(для справки).