Skip to content

Commit

Permalink
Tweaked sort to make it a little faster
Browse files Browse the repository at this point in the history
  • Loading branch information
hosseinmoein committed Sep 3, 2024
1 parent ce2c136 commit f240590
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 109 deletions.
2 changes: 1 addition & 1 deletion include/DataFrame/Internals/DataFrame_functors.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct sort_functor_ : DataVec::template visitor_base<Ts ...> {

const StlVecType<size_t> &sorted_idxs;
const size_t idx_s;
StlVecType<bool> done_vec;
StlVecType<char> done_vec;

template<typename T2>
void operator() (T2 &vec);
Expand Down
139 changes: 53 additions & 86 deletions include/DataFrame/Internals/DataFrame_sort.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,8 @@ sort(const char *name, sort_spec dir, bool ignore_index) {
else {
sort_functor_<Ts ...> 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;
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -578,9 +545,9 @@ sort(const char *name1, sort_spec dir1,
else {
sort_functor_<Ts ...> 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;
}
Expand Down
10 changes: 5 additions & 5 deletions include/DataFrame/Internals/DataFrame_standalone.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down
5 changes: 2 additions & 3 deletions include/DataFrame/Utils/Threads/ThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,9 @@ class ThreadPool {
parallel_loop2(I1 begin1, I1 end1, I2 begin2, I2 end2,
F &&routine, As && ... args);

template<std::random_access_iterator I, long TH = MUL_THR_THHOLD>
template<std::random_access_iterator I, long TH = 50'000L>
void parallel_sort(const I begin, const I end);
template<std::random_access_iterator I, typename P,
long TH = MUL_THR_THHOLD>
template<std::random_access_iterator I, typename P, long TH = 25'000L>
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
Expand Down
26 changes: 12 additions & 14 deletions include/DataFrame/Utils/Threads/ThreadPool.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -294,45 +294,43 @@ 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<I, P, TH>,
this,
begin,
left_iter,
compare);
if (do_right)
if (is_swapped_right)
right_fut = dispatch(false,
&ThreadPool::parallel_sort<I, P, TH>,
this,
right_iter + 1,
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<I, P, TH>(begin, left_iter, compare);
if (is_swapped_left)
std::sort(begin, left_iter, compare);

if (do_right)
parallel_sort<I, P, TH>(right_iter + 1, end, compare);
if (is_swapped_right)
std::sort(right_iter + 1, end, compare);
}
}
}
Expand Down

0 comments on commit f240590

Please sign in to comment.