C ++ 2011 рдореЗрдВ рдорд▓реНрдЯреАрдереНрд░реЗрдбреЗрдб рдХреНрд╡рд┐рдХреЙрд░реНрдЯ

рдирд┐рдЬреА рддреМрд░ рдкрд░, C ++ рдореЗрдВ рдореЗрд░реЗ рд╕рднреА рд╡рд┐рд╢реНрд╡рд╛рд╕реЛрдВ рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ 2011 рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рднреА, рдпрд╣ рднрд╛рд╖рд╛ рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХрд┐рдВрдЧ рдФрд░ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдмреЗрд╣рдж рдЕрдирдлреНрд░реЗрдВрдбрд▓реА рд╣реИред рдЦреБрдж рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреЗ рдПрдХ рдФрд░ рдкреНрд░рдпрд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ рдорд▓реНрдЯреА-рдереНрд░реЗрдбреЗрдб рдХреНрд╡рд┐рдХрд╕реЙрд░реНрдЯ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред

рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдореЗрдВ, рдпрд╣ рд╡рд┐рднрд╛рдЬрди рдЪрд░рдг рдХреЗ рдмрд╛рдж, рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЙрдк-рднрд╛рдЧреЛрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдХрд▓рддрд╛ рд╣реИред

рдпрд╣рд╛рдБ рдореЗрд░реА рднреЛрд▓реА рдмрд╛рдЗрдХ рд╣реИ:

int naive_quick_sort(std::vector<Type>::iterator begin, std::vector<Type>::iterator end) { auto const sz = end - begin; if (sz <= 1) return 0; auto pivot = begin + sz/2; auto const pivot_v = *pivot; std::swap(*pivot, *(end - 1)); auto p = std::partition(begin, end, [&](const Type& a) { return a < pivot_v; } ); std::swap(*p, *(end - 1)); if (sz > 4096) { auto left = std::async(std::launch::async, [&]() { return naive_quick_sort(begin, p); }); naive_quick_sort(p + 1, end); } else { naive_quick_sort(begin, p); naive_quick_sort(p + 1, end); } return 0; } void quick_sort(std::vector<Type>& arr) { naive_quick_sort(arr.begin(), arr.end()); } 

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдерд┐рд░ 4096 рд╣реИ, рдЬреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдкрд░ рд╕реАрдорд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдЕрд░реНрде рдХреНрдпреЛрдВ? рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рд╕рд╛рдорд╛рдиреНрдп рдЬреНрдЮрд╛рди рдХреА рдиреНрдпреВрдирддрдо рднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рд╣рд╡рд╛ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ред рдЬрдм рд╕рдорд╛рдирддрд╛ рд╕рдХреНрд░рд┐рдп рд╣реЛрддреА рд╣реИ, рддреЛ рдмрд╛рдПрдВ рд╕рд░рдгреА рдХреА рдЫрдВрдЯрдиреА рдХреЛ рдПрдХ рдФрд░ рдзрд╛рдЧреЗ рдореЗрдВ рдПрд╕рд┐рдВрдХреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рджрд╛рдПрдВ рдХреЛ рд╡рд░реНрддрдорд╛рди рдзрд╛рдЧреЗ рдореЗрдВ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдХреНрд░рдордмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рдЖрдк рдлрд╝рдВрдХреНрд╢рди рд╕рдВрджрд░реНрдн рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛рддреА рд╣реИ рдХрд┐ async рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ (рд╡реЗ рдЗрд╕рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ)ред

рдкрд░рдВрдкрд░рд╛рдЧрдд рд░реВрдк рд╕реЗ, рдПрдХ рдирд┐рд░реНрд╡рд╛рдд рдореЗрдВ рдЧреЛрд▓рд╛рдХрд╛рд░ рдШреЛрдбрд╝реЛрдВ рдХреА рдкреБрдЬрд╛рд░реЛрдореЗрдХрд╛ред рддреАрди рдЙрдореНрдореАрджрд╡рд╛рд░:

рдкреНрд░рдХрд╛рд░ int64 (рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде) рдХреЗ 50,000,000 рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реЙрд░реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред 10 рдкреНрд░рдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдФрд╕рдд рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдорд╛рди рдЕрдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВ:

 std::tr1::uniform_int<Type> uniform( std::numeric_limits<Type>::min(), std::numeric_limits<Type>::max()); std::mt19937_64 engine; void generate(std::vector<Type>& v) { std::for_each(v.begin(), v.end(), [](Type& i) { i = uniform(engine); }); } 

рдпрд╣ рди рдкреВрдЫреЗрдВ рдХрд┐ рдмрдбрд╝реЗ рдПрдВрдбрд┐рдпрди рд╕реЗ рдЧреЛрд▓-рдпрд╛рддреНрд░рд╛ рдпрд╣рд╛рдВ рдФрд░ рдкреАрдЫреЗ рдХреНрдпреЛрдВ рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ рдЬрд╛рд╡рд╛ рдореЗрдВ рдПрдХ рдЕрдиреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╕рдордп рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рджреМрд░рд╛рди, рдХреЗрд╡рд▓ "рд╢реБрджреНрдз рд╕рдордп" рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХрдВрдкрд╛рдЗрд▓рд░ рд╡реАрдПрд╕ 2011, 64-рдмрд┐рдЯред рдЗрдВрдЯреЗрд▓ рдХреЛрд░ i5 2.53GHz рдкреНрд░реЛрд╕реЗрд╕рд░, 4 рдХреЛрд░ред

   async()   std::sort() --------- --------------- ------------ ------------ 1 2512 6555 7309 2 2337 6320 6977 3 2450 6516 7180 4 2372 6388 6933 5 2387 7074 7189 6 2339 7399 7040 7 2434 6875 7040 8 2562 7060 7187 9 2470 7050 7145 10 2422 6846 6898 --------- --------------- ------------ ------------  2428.5 6808.3 7089.8 

рд╕рдордп рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдореЗрдВ рд╣реИред

рдпрд╣ рддреАрди рдЧреБрдирд╛ рддреЗрдЬреА рд╕реЗ рдХрд╣реАрдВ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИред рдЕрдЬреАрдм рдЫреЛрдЯреЗ рдЕрдВрддрд░рд╛рд▓ std::sort() рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ "рдЕрдЪреНрдЫрд╛" рд╣реИ, рдФрд░ рдореЗрд░рд╛ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрд╕ рдЙрдиреНрд╣реЗрдВ рд╡рд╣рди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ std::sort() рд╕рдордп рд╡рд┐рдЪрд▓рди рдмрд╣реБрдд рдХрдо рд╣реИред рдлрд┐рд░ рднреА, рдбреЗрдЯрд╛ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ stl::sort() рд╕рдордп рд╕реНрдерд┐рд░ рд╣реИред

рдХреНрдпрд╛ рдЗрд╕ рд╕рдорд╛рдирддрд╛ рдХрд╛ рдХреЛрдИ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд▓рд╛рдн рд╣реИ? рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ред рдЕрд▓рдЧ-рдЕрд▓рдЧ рдбреЗрдЯрд╛ рдкрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХрд┐рдВрдЧ рд╢рдЯрдбрд╛рдЙрди рдереНрд░реЗрд╢реЛрд▓реНрдб рдХреИрд╕реЗ рдЪреБрдиреЗрдВ? рдХреНрдпрд╛ рдореБрдЭреЗ рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдпрджрд┐ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдиреАрдЪреЗ рдПрдХ рдбреЗрдЯрд╛ рдЬрдирд░реЗрдЯрд░ рд╕рд╣рд┐рдд рдЗрд╕ рдмрд╛рдЗрдХ рдХрд╛ рдкреВрд░рд╛ рдкрд╛рда рд╣реИред

рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣ рдФрд░ рдкреАрдврд╝реА:

 call "%VS110COMNTOOLS%..\..\VC\vcvarsall.bat" amd64 && ^ cl /Ox /DWIN32 sort_async.cpp && ^ sort_async generate 

рдЪреЗрддрд╛рд╡рдиреА! рдЬрдирд░реЗрдЯрд░ 8 рдЧреАрдЧрд╛ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдмрдирд╛рдПрдЧрд╛ред

рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдФрд░ рдкреНрд░рдпреЛрдЧ:

 call "%VS110COMNTOOLS%..\..\VC\vcvarsall.bat" amd64 && ^ cl /Ox /DWIN32 sort_async.cpp && ^ sort_async 

рдлрд╝рд╛рдЗрд▓ Sort_async.cpp:
 #include <vector> #include <iostream> #include <fstream> #include <sstream> #include <algorithm> #include <iomanip> #include <future> #include <random> #include <chrono> #include <cstdlib> const int ITERATIONS_NUM = 10; const int DATA_SIZE = 50000000; typedef __int64 Type; inline void endian_swap(Type& x) { x = (0x00000000000000FF & (x >> 56)) | (0x000000000000FF00 & (x >> 40)) | (0x0000000000FF0000 & (x >> 24)) | (0x00000000FF000000 & (x >> 8)) | (0x000000FF00000000 & (x << 8)) | (0x0000FF0000000000 & (x << 24)) | (0x00FF000000000000 & (x << 40)) | (0xFF00000000000000 & (x << 56)); } std::tr1::uniform_int<Type> uniform( std::numeric_limits<Type>::min(), std::numeric_limits<Type>::max()); std::mt19937_64 engine; void generate(std::vector<Type>& v) { std::for_each(v.begin(), v.end(), [](Type& i) { i = uniform(engine); }); } void check_sorted(const std::vector<Type>& v, const std::string& msg) { for (auto i = 0; i < v.size() - 1; ++i) { if (v[i] > v[i + 1]) { std::cout << "\nUnsorted: " << msg << "\n"; std::cout << "\n" << i << "\n"; std::cout << v[i] << " " << v[i + 1] << "\n"; std::exit(1); } } } std::string data_file_name(const int i, const std::string& suffix) { std::ostringstream fmt; fmt << "trash_for_sort_" << i << suffix << ".bin"; return fmt.str(); } void save_file(std::vector<Type> array, const std::string& name) { std::for_each(array.begin(), array.end(), [](Type& i) { endian_swap(i); }); std::ofstream os(name.c_str(), std::ios::binary|std::ios::out); auto const bytes_to_write = array.size() * sizeof(array[0]); std::cout << "Saving " << array.size() << " bytes to " << name << "\n"; os.write((char *)&array[0], bytes_to_write); } int main_generate(int argc, char* argv[]) { std::cout << "Generation\n"; for (auto i = 0; i < ITERATIONS_NUM; ++i) { std::vector<Type> unsorted(DATA_SIZE); generate(unsorted); save_file(unsorted, data_file_name(i, "")); std::cout << "Sorting...\n"; std::sort(unsorted.begin(), unsorted.end()); check_sorted(unsorted, "check sorted array"); save_file(unsorted, data_file_name(i, "_sorted")); } return 0; } void load_file(std::vector<Type>& array, const std::string& name) { std::cout << "Loading " << name; array.resize(DATA_SIZE, 0); std::ifstream is(name.c_str(), std::ios::binary|std::ios::in); auto const to_load = array.size() * sizeof(array[0]); is.read((char *)&array[0], to_load); if (is.gcount() != to_load) { std::cerr << ", Bad file " << name << ", loaded " << is.gcount() << " words but should be " << to_load << "\n"; std::exit(1); } std::for_each(array.begin(), array.end(), [](Type& v){ endian_swap(v); }); } int naive_quick_sort(std::vector<Type>::iterator begin, std::vector<Type>::iterator end) { auto const sz = end - begin; if (sz <= 1) return 0; auto pivot = begin + sz/2; auto const pivot_v = *pivot; std::swap(*pivot, *(end - 1)); auto p = std::partition(begin, end, [&](const Type& a) { return a < pivot_v; } ); std::swap(*p, *(end - 1)); if (sz > 4096) { auto left = std::async(std::launch::async, [&]() { return naive_quick_sort(begin, p); }); naive_quick_sort(p + 1, end); } else { naive_quick_sort(begin, p); naive_quick_sort(p + 1, end); } return 0; } void quick_sort(std::vector<Type>& arr) { naive_quick_sort(arr.begin(), arr.end()); } int main(int argc, char* argv[]) { if (argc == 2 && !std::strcmp(argv[1], "generate")) return main_generate(argc, argv); std::vector<double> times; auto times_sum = 0.0; for (auto i = 0; i < ITERATIONS_NUM; ++i) { std::vector<Type> unsorted; load_file(unsorted, data_file_name(i, "")); std::vector<Type> verify; std::cout << ", "; load_file(verify, data_file_name(i, "_sorted")); check_sorted(verify, "verify array"); std::cout << ", Started"; auto start = std::chrono::high_resolution_clock::now(); quick_sort(unsorted); auto stop = std::chrono::high_resolution_clock::now(); std::cout << ", Stopped, "; auto duration = std::chrono::duration<double>(stop - start).count(); std::cout << duration; check_sorted(unsorted, "sorted array"); const auto match = unsorted == verify; std::cout << (match ? ", OK" : ", DON'T MATCH"); times.push_back(duration); times_sum += duration; std::cout << "\n"; } auto const average = times_sum / ITERATIONS_NUM; auto const max_element = *std::max_element(times.begin(), times.end()); auto const min_element = *std::min_element(times.begin(), times.end()); auto const average_fixed = (times_sum - max_element - min_element) / (ITERATIONS_NUM - 2); std::cout << "Average: " << average << "s, " << "Average without max/min: " << average_fixed << "s." << std::endl; } 


рдкрд░реНрджреЗ рдХреА рдУрд░, рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреА рд▓реЛрдбрд┐рдВрдЧ рдХреА рдПрдХ рддрд╕реНрд╡реАрд░ред рдЬрдм рд╕рд┐рд╕реНрдЯрдо рдПрдХ рдЯрд╛рдИрдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдлрдЯрдиреЗ рд╕реНрдкрд╖реНрдЯ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред



additive

рдорд╛рдЗрдХреНрд░реЛрд╕реЙрдлреНрдЯ рдХрд╛ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд▓реЗрдЦ, рдбрд╛рдпрдиреЗрдорд┐рдХ рдЯрд╛рд╕реНрдХ рдкреИрд░реЗрд▓рд┐рдЬреНрдо, рдЬрд┐рд╕рдореЗрдВ рдорд▓реНрдЯреА-рдереНрд░реЗрдбреЗрдб рдХреНрд╡рд┐рдХреЙрд░реНрдЯ рдХрд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рднреА рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

Source: https://habr.com/ru/post/In143055/


All Articles