Use radixSort when possible

This commit is contained in:
Evgenii Pravda 2019-02-18 19:29:37 +03:00
parent cf5265f1be
commit f1e842cdf6
2 changed files with 61 additions and 5 deletions

View File

@ -7,6 +7,7 @@
#include <Common/Arena.h>
#include <Common/SipHash.h>
#include <Common/NaNUtils.h>
#include <Common/RadixSort.h>
#include <IO/WriteBuffer.h>
#include <IO/WriteHelpers.h>
#include <Columns/ColumnsCommon.h>
@ -73,14 +74,15 @@ void ColumnVector<T>::getPermutation(bool reverse, size_t limit, int nan_directi
{
size_t s = data.size();
res.resize(s);
for (size_t i = 0; i < s; ++i)
res[i] = i;
if (limit >= s)
limit = 0;
if (limit)
{
for (size_t i = 0; i < s; ++i)
res[i] = i;
if (reverse)
std::partial_sort(res.begin(), res.begin() + limit, res.end(), greater(*this, nan_direction_hint));
else
@ -88,11 +90,32 @@ void ColumnVector<T>::getPermutation(bool reverse, size_t limit, int nan_directi
}
else
{
if constexpr ((std::is_signed_v<T> || std::is_unsigned_v<T>) && !std::is_same_v<T, UInt128>)
{
PaddedPODArray<std::pair<T, size_t>> pairs(s);
for (size_t i = 0; i < s; ++i)
pairs.data()[i] = {data[i], i};
radixSort(pairs.data(), s);
if (reverse)
for (size_t i = 0; i < s; ++i)
res[s - 1 - i] = pairs[i].second;
else
for (size_t i = 0; i < s; ++i)
res[i] = pairs[i].second;
}
else
{
for (size_t i = 0; i < s; ++i)
res[i] = i;
if (reverse)
pdqsort(res.begin(), res.end(), greater(*this, nan_direction_hint));
else
pdqsort(res.begin(), res.end(), less(*this, nan_direction_hint));
}
}
}
template <typename T>

View File

@ -94,6 +94,22 @@ struct RadixSortFloatTraits
}
};
template <typename Float>
struct RadixSortFloatPTraits
{
using Element = std::pair<Float, size_t>;
using Key = Float;
using CountType = uint32_t;
using KeyBits = std::conditional_t<sizeof(Float) == 8, uint64_t, uint32_t>;
static constexpr size_t PART_SIZE_BITS = 8;
using Transform = RadixSortFloatTransform<KeyBits>;
using Allocator = RadixSortMallocAllocator;
/// The function to get the key from an array element.
static Key & extractKey(Element & elem) { return elem.first; }
};
template <typename KeyBits>
struct RadixSortIdentityTransform
@ -161,6 +177,23 @@ struct RadixSortIntTraits
}
};
template <typename Int>
struct RadixSortIntPTraits
{
using Element = std::pair<Int, size_t>;
using Key = Int;
using CountType = uint32_t;
using KeyBits = std::make_unsigned_t<Int>;
static constexpr size_t PART_SIZE_BITS = 8;
using Transform = RadixSortSignedTransform<KeyBits>;
using Allocator = RadixSortMallocAllocator;
/// The function to get the key from an array element.
static Key & extractKey(Element & elem) { return elem.first; }
};
template <typename Traits>
struct RadixSort