Skip to content

Instantly share code, notes, and snippets.

@martinmoene
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinmoene/59a935cecbb63cdae51e to your computer and use it in GitHub Desktop.
Save martinmoene/59a935cecbb63cdae51e to your computer and use it in GitHub Desktop.
Replacing a loop (compute_loop()) with an std::algorithm.
// replacing a loop (compute_loop()) with an std::algorithm.
#include <algorithm>
#include <functional>
#include <vector>
using Coll = std::vector<int>;
int compute_loop( Coll a, Coll b )
{
int result = 0;
for ( auto i = 0u; i != a.size(); ++i )
{
result = a[i] + b[i] * result;
}
return result;
}
// versus:
int compute_equal( Coll a, Coll b )
{
int result = 0;
std::equal( // or: std::mimatch()
begin( a ), end( a ),
begin( b ),
[&result]( int aa, int bb )
{
return result = aa + bb * result, true;
}
);
return result;
}
// or :
int compute_mismatch( Coll a, Coll b )
{
int result = 0;
std::mismatch(
begin( a ), end( a ),
begin( b ),
[&result]( int aa, int bb )
{
return result = aa + bb * result, true;
}
);
return result;
}
// or (thanks to Jonathan Wakely):
int compute_inner_product( Coll a, Coll b )
{
return std::inner_product(
a.begin(), a.end(),
b.begin(), 0,
[]( int acc, std::pair<int, int> vals )
{
return vals.first + vals.second * acc;
},
[]( int a, int b ) { return std::make_pair( a, b ); }
);
}
// or (thanks to Jonathan Wakely):
int compute_inner_product1( Coll a, Coll b )
{
return std::inner_product(
a.begin(), a.end(),
b.begin(), 0,
[]( int acc, std::pair<int, int> vals )
{
return vals.first + vals.second * acc;
},
&std::make_pair<int&, int&>
);
}
// ...or accentuating the desired operation (becoming less of an improvement):
int compute_inner_product2( Coll a, Coll b )
{
// auto pair_ab = []( int a, int b ) { return std::make_pair( a, b ); };
auto pair_ab = std::make_pair<int&, int&>;
return std::inner_product(
a.begin(), a.end(),
b.begin(), 0,
[]( int acc, std::pair<int, int> vals )
{
return vals.first + vals.second * acc;
},
pair_ab
);
}
// or :
template< typename T>
struct updating_iterator
: public std::iterator< std::output_iterator_tag, T, void, void, void >
{
updating_iterator( T val )
: val_(val) {}
T & operator *() { return val_; }
void operator ++() {};
void operator ++( int ) {};
T val_;
};
int compute_transform( Coll a, Coll b )
{
updating_iterator<int> result( 0 );
return *std::transform(
begin( a ), end( a ),
begin( b ),
result,
[&result]( int aa, int bb )
{
return *result = aa + bb * *result;
}
);
}
// program:
#include <iostream>
int main()
{
Coll a( { 2, 1, } );
Coll b( { 3, 2, } );
std::cout <<
"\nresult loop : " << compute_loop( a, b ) <<
"\nresult equal : " << compute_equal( a, b ) <<
"\nresult mismatch : " << compute_mismatch( a, b ) <<
"\nresult transform: " << compute_transform( a, b ) <<
"\nresult inner_prd: " << compute_inner_product( a, b ) <<
"\nresult inner_pr1: " << compute_inner_product1( a, b ) <<
"\nresult inner_pr2: " << compute_inner_product2( a, b ) <<
"\n";
}
// g++ -Wall -std=c++11 -o loop_vs_algorithm.exe loop_vs_algorithm.cpp && loop_vs_algorithm.exe
//
// result loop : 5
// result equal : 5
// result mismatch : 5
// result transform: 5
// result inner_prd: 5
// result inner_pr1: 5
// result inner_pr2: 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment