Fix abysmally low performance

This commit is contained in:
Alexey Milovidov 2021-05-03 22:56:40 +03:00
parent bad13149ec
commit 0677787d90
4 changed files with 26 additions and 28 deletions

View File

@ -163,45 +163,33 @@ namespace common
return __builtin_smulll_overflow(x, y, &res);
}
/// Overflow check is not implemented for big integers.
template <>
inline bool mulOverflow(Int128 x, Int128 y, Int128 & res)
{
res = mulIgnoreOverflow(x, y);
if (!x || !y)
return false;
UInt128 a = (x > 0) ? x : -x;
UInt128 b = (y > 0) ? y : -y;
return mulIgnoreOverflow(a, b) / b != a;
return false;
}
template <>
inline bool mulOverflow(Int256 x, Int256 y, Int256 & res)
{
res = mulIgnoreOverflow(x, y);
if (!x || !y)
return false;
Int256 a = (x > 0) ? x : -x;
Int256 b = (y > 0) ? y : -y;
return mulIgnoreOverflow(a, b) / b != a;
return false;
}
template <>
inline bool mulOverflow(UInt128 x, UInt128 y, UInt128 & res)
{
res = x * y;
if (!x || !y)
return false;
return (x * y) / y != x;
res = mulIgnoreOverflow(x, y);
return false;
}
template <>
inline bool mulOverflow(UInt256 x, UInt256 y, UInt256 & res)
{
res = mulIgnoreOverflow(x, y);
if (!x || !y)
return false;
return res / y != x;
return false;
}
}

View File

@ -5,10 +5,12 @@
/// (See at http://www.boost.org/LICENSE_1_0.txt)
#include "throwError.h"
#include <cmath>
#include <cfloat>
#include <cassert>
#include <limits>
#include <common/unaligned.h>
namespace wide
@ -526,6 +528,17 @@ private:
res.items[little(2)] = r12 >> 64;
return res;
}
else if constexpr (Bits == 128 && sizeof(base_type) == 8)
{
using CompilerUInt128 = unsigned __int128;
CompilerUInt128 a = (CompilerUInt128(lhs.items[1]) << 64) + lhs.items[0];
CompilerUInt128 b = (CompilerUInt128(rhs.items[1]) << 64) + rhs.items[0];
CompilerUInt128 c = a * b;
integer<Bits, Signed> res;
res.items[0] = c;
res.items[1] = c >> 64;
return res;
}
else
{
integer<Bits, Signed> res{};

View File

@ -246,9 +246,7 @@ inline std::enable_if_t<IsNumber<typename FromDataType::FieldType> && IsDataType
convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
{
typename ToDataType::FieldType result;
convertToDecimalImpl<FromDataType, ToDataType, void>(value, scale, result);
return result;
}

View File

@ -125,7 +125,7 @@ struct ConvertImpl
template <typename Additions = void *>
static ColumnPtr NO_SANITIZE_UNDEFINED execute(
const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type [[maybe_unused]], size_t /*input_rows_count*/,
const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type [[maybe_unused]], size_t input_rows_count,
Additions additions [[maybe_unused]] = Additions())
{
const ColumnWithTypeAndName & named_from = arguments[0];
@ -173,18 +173,17 @@ struct ConvertImpl
const auto & vec_from = col_from->getData();
auto & vec_to = col_to->getData();
size_t size = vec_from.size();
vec_to.resize(size);
vec_to.resize(input_rows_count);
ColumnUInt8::MutablePtr col_null_map_to;
ColumnUInt8::Container * vec_null_map_to [[maybe_unused]] = nullptr;
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>)
{
col_null_map_to = ColumnUInt8::create(size, false);
col_null_map_to = ColumnUInt8::create(input_rows_count, false);
vec_null_map_to = &col_null_map_to->getData();
}
for (size_t i = 0; i < size; ++i)
for (size_t i = 0; i < input_rows_count; ++i)
{
if constexpr (std::is_same_v<FromDataType, DataTypeUUID> != std::is_same_v<ToDataType, DataTypeUUID>)
{
@ -1443,7 +1442,7 @@ private:
ColumnPtr executeInternal(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
if (arguments.empty())
throw Exception{"Function " + getName() + " expects at least 1 arguments",
throw Exception{"Function " + getName() + " expects at least 1 argument",
ErrorCodes::TOO_FEW_ARGUMENTS_FOR_FUNCTION};
const IDataType * from_type = arguments[0].type.get();
@ -1460,7 +1459,7 @@ private:
{
if constexpr (std::is_same_v<RightDataType, DataTypeDateTime64>)
{
// account for optional timezone argument
/// Account for optional timezone argument.
if (arguments.size() != 2 && arguments.size() != 3)
throw Exception{"Function " + getName() + " expects 2 or 3 arguments for DataTypeDateTime64.",
ErrorCodes::TOO_FEW_ARGUMENTS_FOR_FUNCTION};