Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <execution>
- #include <iostream>
- #include <list>
- #include <random>
- #include <string>
- #include <string_view>
- #include <type_traits>
- #include <vector>
- #include <future>
- #include "log_duration.h"
- using namespace std;
- string GenerateWord(mt19937& generator, int max_length) {
- const int length = uniform_int_distribution(1, max_length)(generator);
- string word;
- word.reserve(length);
- for (int i = 0; i < length; ++i) {
- word.push_back(uniform_int_distribution('a', 'z')(generator));
- }
- return word;
- }
- template <template <typename> typename Container>
- Container<string> GenerateDictionary(mt19937& generator, int word_count, int max_length) {
- vector<string> words;
- words.reserve(word_count);
- for (int i = 0; i < word_count; ++i) {
- words.push_back(GenerateWord(generator, max_length));
- }
- return Container(words.begin(), words.end());
- }
- struct Reverser {
- void operator()(string& value) const {
- reverse(value.begin(), value.end());
- }
- };
- template <typename Container, typename Function>
- void Test(string_view mark, Container keys, Function function) {
- LOG_DURATION(mark);
- function(keys, Reverser{});
- }
- #define TEST(function) Test(#function, keys, function<remove_const_t<decltype(keys)>, Reverser>)
- template <typename ForwardRange, typename Function>
- void ForEach1(ForwardRange& range, Function function) {
- for_each(execution::par, range.begin(), range.end(), function);
- }
- template <typename ForwardRange, typename Function>
- void ForEach(ForwardRange& range, Function function) {
- std::vector<std::future<void>> tasks;
- int tmp = range.size()/std::thread::hardware_concurrency();
- size_t range_size = std::max(tmp, 1);
- std::cerr << "Range_size = " << range_size << std::endl;
- tasks.reserve(range_size);
- auto begin = range.begin();
- auto end = range.end();
- for (size_t left = distance(begin, end); left > 0;) {
- const size_t current_page_size = std::min(range_size, left);
- const auto current_page_end = next(begin, current_page_size);
- tasks.push_back( std::async([begin, current_page_end, function] {std::for_each(begin, current_page_end, function);} ));
- left -= current_page_size;
- begin = current_page_end;
- }
- for (size_t i = 0; i < tasks.size(); ++i){
- tasks[i].get();
- }
- }
- int main() {
- // для итераторов с произвольным доступом тоже должно работать
- vector<string> strings = {"cat", "dog", "code"};
- ForEach(strings, [](string& s) {
- reverse(s.begin(), s.end());
- });
- for (string_view s : strings) {
- cout << s << " ";
- }
- cout << endl;
- // вывод: tac god edoc
- mt19937 generator;
- const auto keys = GenerateDictionary<list>(generator, 50'000, 5'000);
- TEST(ForEach1);
- TEST(ForEach);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement