|
|
|
// includes (STL)
|
|
#include <algorithm>
|
|
#include <future>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <thread>
|
|
#include <vector>
|
|
// includes (Wt)
|
|
#include <Wt/WContainerWidget.h>
|
|
|
|
#include "Timer.hpp"
|
|
|
|
using namespace Wt;
|
|
|
|
//!
|
|
//!
|
|
//!
|
|
void testUniqueness()
|
|
{
|
|
static const size_t NumTasks = 100;
|
|
static const size_t ObjectsPerTask = 100000;
|
|
|
|
// task for creating and returning a vector containing 'ObjectsPerTask' WContainerWidgets
|
|
auto createTask = []()
|
|
{
|
|
std::vector<std::unique_ptr<Wt::WContainerWidget>> result;
|
|
result.reserve(ObjectsPerTask);
|
|
for (size_t i = 0; i < ObjectsPerTask; ++i)
|
|
{
|
|
result.emplace_back(std::make_unique<Wt::WContainerWidget>());
|
|
}
|
|
return result;
|
|
};
|
|
|
|
// task for creating and returning a vector containing the string IDs of the passed WContainerWidgets
|
|
// this task also removes duplicated IDs
|
|
auto idTask = [](const std::vector<std::unique_ptr<Wt::WContainerWidget>>& ws, size_t taskId)
|
|
{
|
|
// create IDs
|
|
std::vector<std::string> result;
|
|
result.reserve(ObjectsPerTask);
|
|
for (const auto& w : ws)
|
|
{
|
|
result.emplace_back(w->id());
|
|
}
|
|
// remove duplicates that occured in the current task
|
|
std::sort(std::begin(result), std::end(result));
|
|
result.erase(std::unique(std::begin(result), std::end(result)), std::end(result));
|
|
|
|
return result;
|
|
};
|
|
|
|
std::cout << "creating widgets ...\n";
|
|
std::vector<std::future<std::vector<std::unique_ptr<Wt::WContainerWidget>>>> wfs;
|
|
wfs.reserve(NumTasks);
|
|
// spawn 'NumTasks' threads, each performing the 'createTask' task
|
|
for (size_t i = 0; i < NumTasks; ++i)
|
|
{
|
|
wfs.emplace_back(std::async(std::launch::async, createTask));
|
|
}
|
|
// wait for all tasks to finish
|
|
for (const auto& f : wfs)
|
|
{
|
|
f.wait();
|
|
}
|
|
|
|
std::cout << "creating ids ...\n";
|
|
std::vector<std::future<std::vector<std::string>>> idfs;
|
|
idfs.reserve(NumTasks);
|
|
// spawn 'NumTasks' threads, each performing the 'idTask' task for one of the results
|
|
// from previously executed 'createTask'
|
|
for (size_t i = 0; i < NumTasks; ++i)
|
|
{
|
|
idfs.emplace_back(std::async(std::launch::async, idTask, wfs[i].get(), i));
|
|
}
|
|
// wait for all tasks to finish
|
|
for (const auto& f : idfs)
|
|
{
|
|
f.wait();
|
|
}
|
|
|
|
std::cout << "merging ids & removing duplicates ...\n\n";
|
|
std::vector<std::string> ids;
|
|
ids.reserve(NumTasks * ObjectsPerTask);
|
|
for (size_t i = 0; i < NumTasks; ++i)
|
|
{
|
|
// get the string IDs for task #i
|
|
auto tmp = idfs[i].get();
|
|
|
|
// print the number of WContainerWidgets with unique IDs built in task #i
|
|
// (duplicates already removed in 'idTask')
|
|
std::cout << "task #" << i << ": " << tmp.size() << " of " << ObjectsPerTask << " ids are unique\n";
|
|
|
|
// add all IDs container for all IDs
|
|
ids.insert(std::end(ids), std::make_move_iterator(std::begin(tmp)), std::make_move_iterator(std::end(tmp)));
|
|
}
|
|
|
|
// remove all duplicated IDs that occured in any task
|
|
std::sort(std::begin(ids), std::end(ids));
|
|
ids.erase(std::unique(std::begin(ids), std::end(ids)), std::end(ids));
|
|
std::cout << "\noverall: " << ids.size() << " of " << NumTasks * ObjectsPerTask << " ids are unique\n\n";
|
|
}
|
|
|
|
//!
|
|
//!
|
|
//!
|
|
void measurePerformance()
|
|
{
|
|
static size_t N = 5000000;
|
|
|
|
double elapsed = 0;
|
|
for (size_t k = 0; k < 10; ++k)
|
|
{
|
|
std::vector<std::unique_ptr<Wt::WContainerWidget>> ws;
|
|
ws.reserve(N);
|
|
|
|
sk::tools::Timer t;
|
|
t.start();
|
|
|
|
for (size_t i = 0; i < N; ++i)
|
|
{
|
|
ws.emplace_back(std::make_unique<Wt::WContainerWidget>());
|
|
}
|
|
|
|
t.stop();
|
|
elapsed += t.elapsed();
|
|
std::cout << "elapsed time #" << k << ": " << t.elapsed() << "ms\n";
|
|
}
|
|
|
|
std::cout << "elapsed time (mean): " << elapsed / 10 << "ms\n\n";
|
|
}
|
|
|
|
//!
|
|
//!
|
|
//!
|
|
int main(int argc, char** args)
|
|
{
|
|
testUniqueness();
|
|
measurePerformance();
|
|
|
|
return 0;
|
|
}
|