Last active
August 29, 2015 14:21
-
-
Save martinmoene/59a935cecbb63cdae51e to your computer and use it in GitHub Desktop.
Replacing a loop (compute_loop()) with an std::algorithm.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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