#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <chrono>
using namespace std;
string const delim = ", ";
string join_auto(vector<string> const& v)
{
string ret;
if (! v.empty()) {
ret = v[0];
for (auto i = v.begin() + 1; i != v.end(); ++i) { ret += delim; ret += *i; }
}
return ret;
}
string join_foreach(vector<string> const& v)
{
string ret;
if (! v.empty()) {
ret = v[0];
for_each(v.begin() + 1, v.end(), [&](string const& s){ ret += delim; ret += s; });
}
return ret;
}
string join_rangefor(vector<string> const& v)
{
string ret;
for (auto const& s : v) { ret += s; ret += delim; }
if (! v.empty()) { ret.resize(ret.size() - delim.size()); }
return ret;
}
string join_sstream(vector<string> const& v)
{
ostringstream ss;
copy(v.begin(), v.end(), ostream_iterator<string>(ss, delim.c_str()));
return ss.str();
}
string join_accum(vector<string> const& v)
{
return accumulate(v.begin(), v.end(), string(),
[](string const& a, string const& b) -> string { return a + delim + b; });
}
string join_accum_move(vector<string> const& v)
{
return accumulate(v.begin(), v.end(), string(),
[](string& a, string const& b) -> string { return move(a) + delim + b; });
}
template <string F(vector<string> const&)>
void test(int n, vector<string> const& v, string const& name)
{
using namespace std::chrono;
auto start = high_resolution_clock::now();
for (int i = 0; i < n; ++i)
{
F(v);
}
auto ms = duration_cast<milliseconds>(high_resolution_clock::now() - start);
cout << ms.count() << "ms\t-- " << name << endl;
}
#define TEST(N, V, F) (test<(F)>((N), (V), #F))
int main()
{
vector<pair<int, int>> counts { {1000,100}, {1000,1000}, {1000,10000} };
for (auto const& n : counts)
{
cout << endl << "Testing with " << n.first;
cout << " vectors of " << n.second << " strings:" << endl;
vector<string> v;
v.insert(v.begin(), n.second, "foobar");
TEST(n.first, v, join_auto);
TEST(n.first, v, join_foreach);
TEST(n.first, v, join_rangefor);
TEST(n.first, v, join_sstream);
TEST(n.first, v, join_accum);
TEST(n.first, v, join_accum_move);
}
}