|
9 | 9 | #define XSS_HIDE_SYMBOL __attribute__((visibility("hidden"))) |
10 | 10 | #define UNUSED(x) (void)(x) |
11 | 11 |
|
12 | | -template <typename T> |
13 | | -XSS_HIDE_SYMBOL void permute_array_in_place(T *A, std::vector<size_t> P) |
14 | | -{ |
15 | | - for (size_t i = 0; i < P.size(); i++) { |
16 | | - size_t curr = i; |
17 | | - size_t next = P[curr]; |
18 | | - while (next != i) { |
19 | | - std::swap(A[curr], A[next]); |
20 | | - P[curr] = curr; |
21 | | - curr = next; |
22 | | - next = P[next]; |
23 | | - } |
24 | | - P[curr] = curr; |
25 | | - } |
26 | | -} |
27 | | - |
28 | 12 | namespace x86simdsort { |
29 | 13 |
|
30 | 14 | // quicksort |
@@ -55,14 +39,30 @@ argselect(T *arr, size_t k, size_t arrsize, bool hasnan = false); |
55 | 39 | template <typename T, typename F> |
56 | 40 | XSS_EXPORT_SYMBOL void object_qsort(T *arr, size_t arrsize, const F key_func) |
57 | 41 | { |
| 42 | + /* (1) Create a vector a keys */ |
58 | 43 | using return_type_of = |
59 | 44 | typename decltype(std::function {key_func})::result_type; |
60 | | - std::vector<return_type_of> keys(arrsize); |
| 45 | + std::vector<return_type_of> keys; |
| 46 | + keys.reserve(arrsize); |
61 | 47 | for (size_t ii = 0; ii < arrsize; ++ii) { |
62 | 48 | keys[ii] = key_func(arr[ii]); |
63 | 49 | } |
| 50 | + |
| 51 | + /* (2) Call argsort based on the keys */ |
64 | 52 | std::vector<size_t> arg = x86simdsort::argsort(keys.data(), arrsize); |
65 | | - permute_array_in_place(arr, arg); |
| 53 | + |
| 54 | + /* (3) Permute array in-place */ |
| 55 | + for (size_t i = 0; i < arrsize; i++) { |
| 56 | + size_t curr = i; |
| 57 | + size_t next = arg[curr]; |
| 58 | + while (next != i) { |
| 59 | + std::swap(arr[curr], arr[next]); |
| 60 | + arg[curr] = curr; |
| 61 | + curr = next; |
| 62 | + next = arg[next]; |
| 63 | + } |
| 64 | + arg[curr] = curr; |
| 65 | + } |
66 | 66 | } |
67 | 67 |
|
68 | 68 | } // namespace x86simdsort |
|
0 commit comments