mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Attempt to improve performance of formatting Date and DateTime [#CLICKHOUSE-2].
This commit is contained in:
parent
040b4bd47e
commit
ee48dea0d3
@ -498,110 +498,126 @@ inline void writeUUIDText(const UUID & uuid, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
/// in YYYY-MM-DD format
|
||||
inline void writeDateText(DayNum_t date, WriteBuffer & buf)
|
||||
{
|
||||
char s[10] = {'0', '0', '0', '0', '-', '0', '0', '-', '0', '0'};
|
||||
|
||||
if (unlikely(date > DATE_LUT_MAX_DAY_NUM || date == 0))
|
||||
{
|
||||
buf.write(s, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto & values = DateLUT::instance().getValues(date);
|
||||
|
||||
s[0] += values.year / 1000;
|
||||
s[1] += (values.year / 100) % 10;
|
||||
s[2] += (values.year / 10) % 10;
|
||||
s[3] += values.year % 10;
|
||||
s[5] += values.month / 10;
|
||||
s[6] += values.month % 10;
|
||||
s[8] += values.day_of_month / 10;
|
||||
s[9] += values.day_of_month % 10;
|
||||
|
||||
buf.write(s, 10);
|
||||
}
|
||||
|
||||
template <char delimiter = '-'>
|
||||
inline void writeDateText(const LocalDate & date, WriteBuffer & buf)
|
||||
{
|
||||
char s[10] = {'0', '0', '0', '0', '-', '0', '0', '-', '0', '0'};
|
||||
static const char digits[201] =
|
||||
"00010203040506070809"
|
||||
"10111213141516171819"
|
||||
"20212223242526272829"
|
||||
"30313233343536373839"
|
||||
"40414243444546474849"
|
||||
"50515253545556575859"
|
||||
"60616263646566676869"
|
||||
"70717273747576777879"
|
||||
"80818283848586878889"
|
||||
"90919293949596979899";
|
||||
|
||||
s[0] += date.year() / 1000;
|
||||
s[1] += (date.year() / 100) % 10;
|
||||
s[2] += (date.year() / 10) % 10;
|
||||
s[3] += date.year() % 10;
|
||||
s[5] += date.month() / 10;
|
||||
s[6] += date.month() % 10;
|
||||
s[8] += date.day() / 10;
|
||||
s[9] += date.day() % 10;
|
||||
|
||||
buf.write(s, 10);
|
||||
}
|
||||
|
||||
|
||||
/// in the format YYYY-MM-DD HH:MM:SS, according to the current time zone
|
||||
template <char date_delimeter = '-', char time_delimeter = ':'>
|
||||
inline void writeDateTimeText(time_t datetime, WriteBuffer & buf, const DateLUTImpl & date_lut = DateLUT::instance())
|
||||
if (buf.position() + 10 <= buf.buffer().end())
|
||||
{
|
||||
char s[19] = {'0', '0', '0', '0', date_delimeter, '0', '0', date_delimeter, '0', '0', ' ', '0', '0', time_delimeter, '0', '0', time_delimeter, '0', '0'};
|
||||
|
||||
if (unlikely(datetime > DATE_LUT_MAX || datetime == 0))
|
||||
memcpy(buf.position(), &digits[date.year() / 100 * 2], 2);
|
||||
buf.position() += 2;
|
||||
memcpy(buf.position(), &digits[date.year() % 100 * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = delimiter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[date.month() * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = delimiter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[date.day() * 2], 2);
|
||||
buf.position() += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.write(s, 19);
|
||||
return;
|
||||
buf.write(&digits[date.year() / 100 * 2], 2);
|
||||
buf.write(&digits[date.year() % 100 * 2], 2);
|
||||
buf.write(delimiter);
|
||||
buf.write(&digits[date.month() * 2], 2);
|
||||
buf.write(delimiter);
|
||||
buf.write(&digits[date.day() * 2], 2);
|
||||
}
|
||||
}
|
||||
|
||||
const auto & values = date_lut.getValues(datetime);
|
||||
|
||||
s[0] += values.year / 1000;
|
||||
s[1] += (values.year / 100) % 10;
|
||||
s[2] += (values.year / 10) % 10;
|
||||
s[3] += values.year % 10;
|
||||
s[5] += values.month / 10;
|
||||
s[6] += values.month % 10;
|
||||
s[8] += values.day_of_month / 10;
|
||||
s[9] += values.day_of_month % 10;
|
||||
|
||||
UInt8 hour = date_lut.toHour(datetime);
|
||||
UInt8 minute = date_lut.toMinute(datetime);
|
||||
UInt8 second = date_lut.toSecond(datetime);
|
||||
|
||||
s[11] += hour / 10;
|
||||
s[12] += hour % 10;
|
||||
s[14] += minute / 10;
|
||||
s[15] += minute % 10;
|
||||
s[17] += second / 10;
|
||||
s[18] += second % 10;
|
||||
|
||||
buf.write(s, 19);
|
||||
template <char delimiter = '-'>
|
||||
inline void writeDateText(DayNum_t date, WriteBuffer & buf)
|
||||
{
|
||||
writeDateText<delimiter>(LocalDate(date), buf);
|
||||
}
|
||||
|
||||
template <char date_delimeter = '-', char time_delimeter = ':'>
|
||||
|
||||
/// In the format YYYY-MM-DD HH:MM:SS
|
||||
template <char date_delimeter = '-', char time_delimeter = ':', char between_date_time_delimiter = ' '>
|
||||
inline void writeDateTimeText(const LocalDateTime & datetime, WriteBuffer & buf)
|
||||
{
|
||||
char s[19] = {'0', '0', '0', '0', date_delimeter, '0', '0', date_delimeter, '0', '0', ' ', '0', '0', time_delimeter, '0', '0', time_delimeter, '0', '0'};
|
||||
static const char digits[201] =
|
||||
"00010203040506070809"
|
||||
"10111213141516171819"
|
||||
"20212223242526272829"
|
||||
"30313233343536373839"
|
||||
"40414243444546474849"
|
||||
"50515253545556575859"
|
||||
"60616263646566676869"
|
||||
"70717273747576777879"
|
||||
"80818283848586878889"
|
||||
"90919293949596979899";
|
||||
|
||||
s[0] += datetime.year() / 1000;
|
||||
s[1] += (datetime.year() / 100) % 10;
|
||||
s[2] += (datetime.year() / 10) % 10;
|
||||
s[3] += datetime.year() % 10;
|
||||
s[5] += datetime.month() / 10;
|
||||
s[6] += datetime.month() % 10;
|
||||
s[8] += datetime.day() / 10;
|
||||
s[9] += datetime.day() % 10;
|
||||
if (buf.position() + 19 <= buf.buffer().end())
|
||||
{
|
||||
memcpy(buf.position(), &digits[datetime.year() / 100 * 2], 2);
|
||||
buf.position() += 2;
|
||||
memcpy(buf.position(), &digits[datetime.year() % 100 * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = date_delimeter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[datetime.month() * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = date_delimeter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[datetime.day() * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = between_date_time_delimiter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[datetime.hour() * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = time_delimeter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[datetime.minute() * 2], 2);
|
||||
buf.position() += 2;
|
||||
*buf.position() = time_delimeter;
|
||||
++buf.position();
|
||||
memcpy(buf.position(), &digits[datetime.second() * 2], 2);
|
||||
buf.position() += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.write(&digits[datetime.year() / 100 * 2], 2);
|
||||
buf.write(&digits[datetime.year() % 100 * 2], 2);
|
||||
buf.write(date_delimeter);
|
||||
buf.write(&digits[datetime.month() * 2], 2);
|
||||
buf.write(date_delimeter);
|
||||
buf.write(&digits[datetime.day() * 2], 2);
|
||||
buf.write(between_date_time_delimiter);
|
||||
buf.write(&digits[datetime.hour() * 2], 2);
|
||||
buf.write(time_delimeter);
|
||||
buf.write(&digits[datetime.minute() * 2], 2);
|
||||
buf.write(time_delimeter);
|
||||
buf.write(&digits[datetime.second() * 2], 2);
|
||||
}
|
||||
}
|
||||
|
||||
s[11] += datetime.hour() / 10;
|
||||
s[12] += datetime.hour() % 10;
|
||||
s[14] += datetime.minute() / 10;
|
||||
s[15] += datetime.minute() % 10;
|
||||
s[17] += datetime.second() / 10;
|
||||
s[18] += datetime.second() % 10;
|
||||
|
||||
buf.write(s, 19);
|
||||
/// In the format YYYY-MM-DD HH:MM:SS, according to the specified time zone.
|
||||
template <char date_delimeter = '-', char time_delimeter = ':', char between_date_time_delimiter = ' '>
|
||||
inline void writeDateTimeText(time_t datetime, WriteBuffer & buf, const DateLUTImpl & date_lut = DateLUT::instance())
|
||||
{
|
||||
const auto & values = date_lut.getValues(datetime);
|
||||
writeDateTimeText<date_delimeter, time_delimeter, between_date_time_delimiter>(
|
||||
LocalDateTime(values.year, values.month, values.day_of_month,
|
||||
date_lut.toHour(datetime), date_lut.toMinute(datetime), date_lut.toSecond(datetime)), buf);
|
||||
}
|
||||
|
||||
|
||||
/// Methods of output in binary form
|
||||
/// Methods for output in binary format.
|
||||
template <typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||
writeBinary(const T & x, WriteBuffer & buf) { writePODBinary(x, buf); }
|
||||
|
Loading…
Reference in New Issue
Block a user