From f240590f1972647fe3ce672da34608a9d62663d8 Mon Sep 17 00:00:00 2001 From: Hossein Moein Date: Tue, 3 Sep 2024 10:33:49 -0400 Subject: [PATCH] Tweaked sort to make it a little faster --- .../DataFrame/Internals/DataFrame_functors.h | 2 +- .../DataFrame/Internals/DataFrame_sort.tcc | 139 +++++++----------- .../Internals/DataFrame_standalone.tcc | 10 +- include/DataFrame/Utils/Threads/ThreadPool.h | 5 +- .../DataFrame/Utils/Threads/ThreadPool.tcc | 26 ++-- 5 files changed, 73 insertions(+), 109 deletions(-) diff --git a/include/DataFrame/Internals/DataFrame_functors.h b/include/DataFrame/Internals/DataFrame_functors.h index c1a629c2..b71011c4 100644 --- a/include/DataFrame/Internals/DataFrame_functors.h +++ b/include/DataFrame/Internals/DataFrame_functors.h @@ -83,7 +83,7 @@ struct sort_functor_ : DataVec::template visitor_base { const StlVecType &sorted_idxs; const size_t idx_s; - StlVecType done_vec; + StlVecType done_vec; template void operator() (T2 &vec); diff --git a/include/DataFrame/Internals/DataFrame_sort.tcc b/include/DataFrame/Internals/DataFrame_sort.tcc index debe1116..29cd747a 100644 --- a/include/DataFrame/Internals/DataFrame_sort.tcc +++ b/include/DataFrame/Internals/DataFrame_sort.tcc @@ -154,9 +154,8 @@ sort(const char *name, sort_spec dir, bool ignore_index) { else { sort_functor_ functor (sorting_idxs, idx_s); - for (const auto &citer : column_list_) [[likely]] - if (citer.first != name) - data_[citer.second].change(functor); + for (const auto &[this_name, idx] : column_list_) [[likely]] + if (this_name != name) data_[idx].change(functor); } return; } @@ -195,131 +194,99 @@ sort(const char *name1, sort_spec dir1, auto a_a = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) < std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) > std::get<0>(rhs)) - return (false); - return (std::get<1>(lhs) < std::get<1>(rhs)); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (std::get<1>(lhs) < std::get<1>(rhs)); + return (std::get<0>(lhs) < std::get<0>(rhs)); }; auto d_d = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) > std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) < std::get<0>(rhs)) - return (false); - return (std::get<1>(lhs) > std::get<1>(rhs)); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (std::get<1>(lhs) > std::get<1>(rhs)); + return (std::get<0>(lhs) > std::get<0>(rhs)); }; auto a_d = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) < std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) > std::get<0>(rhs)) - return (false); - return (std::get<1>(lhs) > std::get<1>(rhs)); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (std::get<1>(lhs) > std::get<1>(rhs)); + return (std::get<0>(lhs) < std::get<0>(rhs)); }; auto d_a = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) > std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) < std::get<0>(rhs)) - return (false); - return (std::get<1>(lhs) < std::get<1>(rhs)); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (std::get<1>(lhs) < std::get<1>(rhs)); + return (std::get<0>(lhs) > std::get<0>(rhs)); }; auto aa_aa = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (false); - return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + return (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))); }; auto ad_ad = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (false); - return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + return (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))); }; auto aa_ad = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (false); - return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + return (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))); }; auto ad_aa = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (false); - return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + return (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))); }; auto a_aa = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) < std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) > std::get<0>(rhs)) - return (false); - return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + return (std::get<0>(lhs) < std::get<0>(rhs)); }; auto a_ad = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) < std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) > std::get<0>(rhs)) - return (false); - return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + return (std::get<0>(lhs) < std::get<0>(rhs)); }; auto d_aa = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) > std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) < std::get<0>(rhs)) - return (false); - return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (abs__(std::get<1>(lhs)) < abs__(std::get<1>(rhs))); + return (std::get<0>(lhs) > std::get<0>(rhs)); }; auto d_ad = [](const auto &lhs, const auto &rhs) -> bool { - if (std::get<0>(lhs) > std::get<0>(rhs)) - return (true); - else if (std::get<0>(lhs) < std::get<0>(rhs)) - return (false); - return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + if (std::get<0>(lhs) == std::get<0>(rhs)) + return (abs__(std::get<1>(lhs)) > abs__(std::get<1>(rhs))); + return (std::get<0>(lhs) > std::get<0>(rhs)); }; auto aa_a = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (false); - return (std::get<1>(lhs) < std::get<1>(rhs)); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (std::get<1>(lhs) < std::get<1>(rhs)); + return (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))); }; auto ad_a = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (false); - return (std::get<1>(lhs) < std::get<1>(rhs)); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (std::get<1>(lhs) < std::get<1>(rhs)); + return (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))); }; auto aa_d = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (false); - return (std::get<1>(lhs) > std::get<1>(rhs)); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (std::get<1>(lhs) > std::get<1>(rhs)); + return (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))); }; auto ad_d = [](const auto &lhs, const auto &rhs) -> bool { - if (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))) - return (true); - else if (abs__(std::get<0>(lhs)) < abs__(std::get<0>(rhs))) - return (false); - return (std::get<1>(lhs) > std::get<1>(rhs)); + if (abs__(std::get<0>(lhs)) == abs__(std::get<0>(rhs))) + return (std::get<1>(lhs) > std::get<1>(rhs)); + return (abs__(std::get<0>(lhs)) > abs__(std::get<0>(rhs))); }; const size_type idx_s = indices_.size(); @@ -578,9 +545,9 @@ sort(const char *name1, sort_spec dir1, else { sort_functor_ functor (sorting_idxs, idx_s); - for (const auto &citer : column_list_) [[likely]] - if (citer.first != name1 && citer.first != name2) - data_[citer.second].change(functor); + for (const auto &[name, idx] : column_list_) [[likely]] + if (name != name1 && name != name2) + data_[idx].change(functor); } return; } diff --git a/include/DataFrame/Internals/DataFrame_standalone.tcc b/include/DataFrame/Internals/DataFrame_standalone.tcc index e4f6bdfd..3187c93b 100644 --- a/include/DataFrame/Internals/DataFrame_standalone.tcc +++ b/include/DataFrame/Internals/DataFrame_standalone.tcc @@ -1924,17 +1924,17 @@ _sort_by_sorted_index_(T &to_be_sorted, BV &done_vec, size_t idx_s) { - std::ranges::fill(done_vec, false); + std::ranges::fill(done_vec, 0); for (std::size_t i = 0; i < idx_s; ++i) [[likely]] { - if (! done_vec[i]) { - done_vec[i] = true; + if (! done_vec[i]) [[likely]] { + done_vec[i] = 1; std::size_t prev_j = i; std::size_t j = sorting_idxs[i]; - while (i != j) { + while (i != j) [[likely]] { std::swap(to_be_sorted[prev_j], to_be_sorted[j]); - done_vec[j] = true; + done_vec[j] = 1; prev_j = j; j = sorting_idxs[j]; } diff --git a/include/DataFrame/Utils/Threads/ThreadPool.h b/include/DataFrame/Utils/Threads/ThreadPool.h index dcc5a0b7..8839e3a5 100644 --- a/include/DataFrame/Utils/Threads/ThreadPool.h +++ b/include/DataFrame/Utils/Threads/ThreadPool.h @@ -114,10 +114,9 @@ class ThreadPool { parallel_loop2(I1 begin1, I1 end1, I2 begin2, I2 end2, F &&routine, As && ... args); - template + template void parallel_sort(const I begin, const I end); - template + template void parallel_sort(const I begin, const I end, P compare); // If the pool is not shutdown and there is a pending task, run the one diff --git a/include/DataFrame/Utils/Threads/ThreadPool.tcc b/include/DataFrame/Utils/Threads/ThreadPool.tcc index 818649ba..46bf79e7 100644 --- a/include/DataFrame/Utils/Threads/ThreadPool.tcc +++ b/include/DataFrame/Utils/Threads/ThreadPool.tcc @@ -271,12 +271,12 @@ ThreadPool::parallel_sort(const I begin, const I end, P compare) { const size_type data_size = std::distance(begin, end); - if (data_size > 0) { + if (data_size > 1) { auto left_iter = begin; auto right_iter = end - 1; bool is_swapped_left = false; bool is_swapped_right = false; - const value_type pivot = *begin; + const value_type pivot = *(begin + (data_size / 2)); auto fwd_iter = begin + 1; while (fwd_iter <= right_iter) { @@ -294,23 +294,21 @@ ThreadPool::parallel_sort(const I begin, const I end, P compare) { else ++fwd_iter; } - const bool do_left = - is_swapped_left && std::distance(begin, left_iter) > 0; - const bool do_right = - is_swapped_right && std::distance(right_iter, end) > 0; + is_swapped_left &= begin < left_iter; + is_swapped_right &= right_iter < end; if (data_size >= TH) { fut_type left_fut; fut_type right_fut; - if (do_left) + if (is_swapped_left) left_fut = dispatch(false, &ThreadPool::parallel_sort, this, begin, left_iter, compare); - if (do_right) + if (is_swapped_right) right_fut = dispatch(false, &ThreadPool::parallel_sort, this, @@ -318,21 +316,21 @@ ThreadPool::parallel_sort(const I begin, const I end, P compare) { end, compare); - if (do_left) + if (is_swapped_left) while (left_fut.wait_for(std::chrono::seconds(0)) == std::future_status::timeout) run_task(); - if (do_right) + if (is_swapped_right) while (right_fut.wait_for(std::chrono::seconds(0)) == std::future_status::timeout) run_task(); } else { - if (do_left) - parallel_sort(begin, left_iter, compare); + if (is_swapped_left) + std::sort(begin, left_iter, compare); - if (do_right) - parallel_sort(right_iter + 1, end, compare); + if (is_swapped_right) + std::sort(right_iter + 1, end, compare); } } }