Skip to content

Commit

Permalink
LLBC_Time::FromTimeStr()性能优化 #260
Browse files Browse the repository at this point in the history
  • Loading branch information
lailongwei committed Sep 18, 2024
1 parent 13dbb45 commit 89a5f2b
Show file tree
Hide file tree
Showing 6 changed files with 375 additions and 220 deletions.
15 changes: 15 additions & 0 deletions llbc/include/llbc/core/time/Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class LLBC_EXPORT LLBC_Time final
static LLBC_Time FromMicros(sint64 clanderTimeInMicros);
static LLBC_Time FromTimeVal(const timeval &timeVal);
static LLBC_Time FromTimeSpec(const timespec &timeSpec);
template <size_t _StrArrLen>
static LLBC_Time FromTimeStr(const char (&timeStr)[_StrArrLen]);
static LLBC_Time FromTimeStr(const char *timeStr);
template <typename _StrType>
static typename std::enable_if<LLBC_IsTemplSpec<_StrType, std::basic_string>::value, LLBC_Time>::type
FromTimeStr(const _StrType &timeStr);
static LLBC_Time FromTimeStr(const LLBC_String &timeStr);
static LLBC_Time FromTimeStruct(const tm &timeStruct,
int milliSec = 0,
Expand Down Expand Up @@ -314,6 +320,15 @@ class LLBC_EXPORT LLBC_Time final
bool Deserialize(LLBC_Stream &stream);

private:
/**
* Construct Time object from time string representation.
*
* @param[in] timeStr - the time string representatin, eg: 2024-09-10 18:19:30.123456
* @param[in] timeStrLen - the time string length, not included '\0'.
* @return LLBC_Time - time obuect.
*/
static LLBC_Time FromTimeStr(const char *timeStr, size_t timeStrLen);

/**
* Internal constructor.
* @param clendarTimeInMicroseconds - calendar time in microseconds.
Expand Down
23 changes: 23 additions & 0 deletions llbc/include/llbc/core/time/TimeInl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ inline LLBC_Time LLBC_Time::FromTimeSpec(const timespec &timeSpec)
timeSpec.tv_nsec / LLBC_TimeConst::numOfNanosPerMicrosecond);
}

template <size_t _StrArrLen>
LLBC_Time LLBC_Time::FromTimeStr(const char (&timeStr)[_StrArrLen])
{
return FromTimeStr(timeStr, _StrArrLen - 1);
}

inline LLBC_Time LLBC_Time::FromTimeStr(const char *timeStr)
{
return FromTimeStr(timeStr, strlen(timeStr));
}

template <typename _StrType>
typename std::enable_if<LLBC_IsTemplSpec<_StrType, std::basic_string>::value, LLBC_Time>::type
LLBC_Time::FromTimeStr(const _StrType &timeStr)
{
return FromTimeStr(timeStr.c_str(), timeStr.size());
}

inline LLBC_Time LLBC_Time::FromTimeStr(const LLBC_String &timeStr)
{
return FromTimeStr(timeStr.c_str(), timeStr.size());
}

inline int LLBC_Time::GetYear() const
{
return _localTimeStruct.tm_year + 1900; // scene 1900
Expand Down
124 changes: 0 additions & 124 deletions llbc/include/llbc/core/time/TimeSpanInl.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,128 +351,4 @@ inline bool LLBC_TimeSpan::Deserialize(LLBC_Stream &stream)
return true;
}

#define __LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(partStr, partLen, spanFactor) \
if (UNLIKELY(partLen >= sizeof(numFmtBuf))) \
{ \
_span = 0; \
return; \
} \
memcpy(numFmtBuf, partStr, partLen); \
numFmtBuf[partLen] = '\0'; \
_span += atoi(numFmtBuf) * spanFactor; \

inline LLBC_TimeSpan::LLBC_TimeSpan(const char *spanStr, size_t spanStrLen)
: _span(0)
{
// Time span string format:
// - [DD ][[HH:]MM:]SS[.micro_sec]
//
// eg:
// DD HH MM SS micro_sec
// 03 => 3 + 0 seconds
// 02:03 => 2*60 + 3 + 0 seconds
// 01:02:03 => 1*3600 + 2*60 + 3 + 0 seconds
// 8 01:02:03 => 8*86400 + 1*3600 + 2*60 + 3 + 0 seconds
// 8 01:02:03.4 => 8*86400 + 1*3600 + 2*60 + 3 + 4*0.000001 seconds
// Argument check.
if (UNLIKELY(!spanStr || spanStrLen == 0))
return;

// Remove leading whitespace characters.
const char *origSpanStr = spanStr;
while (*spanStr != '\0')
{
LLBC_BreakIf(LIKELY(!LLBC_IsSpace(*spanStr)));
++spanStr;
}

if (*spanStr == '\0')
return;
spanStrLen -= static_cast<size_t>(spanStr - origSpanStr);

// Remove trailing whitespace characters.
const char *spanStrEnd = spanStr + spanStrLen - 1;
while (spanStrEnd != spanStr && LLBC_IsSpace(*spanStrEnd))
--spanStrEnd;

++spanStrEnd;
spanStrLen = static_cast<size_t>(spanStrEnd - spanStr);

// Parse time span string, format:
// - Parse <DD> part.
char numFmtBuf[12];
const char *dayPartEnd = spanStr;
while (++dayPartEnd != spanStrEnd)
LLBC_BreakIf(LLBC_IsSpace(*dayPartEnd));
if (dayPartEnd != spanStrEnd)
{
size_t dayPartLen = static_cast<size_t>(dayPartEnd - spanStr);
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(spanStr, dayPartLen, LLBC_TimeConst::numOfMicrosPerDay);

spanStr = dayPartEnd + 1;
// spanStrLen -= (dayPartLen + 1); // <spanStrLen> variable is no longer used after this point.
}

// - Search all colons pos.
size_t colonSize = 0;
const char *colonPoses[2]{nullptr, nullptr};
const char *strIt = spanStr;
while (strIt != spanStrEnd)
{
if (*strIt == ':')
{
colonPoses[colonSize++] = strIt;
if (colonSize == 2)
break;
}

++strIt;
}

// - Parse <HH:MM> part.
const char *secPart;
if (colonSize == 2)
{
size_t partLen = static_cast<size_t>(colonPoses[0] - spanStr);
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(spanStr, partLen, LLBC_TimeConst::numOfMicrosPerHour);

partLen = static_cast<size_t>(colonPoses[1] - colonPoses[0] - 1);
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(colonPoses[0] + 1, partLen, LLBC_TimeConst::numOfMicrosPerMinute);

secPart = colonPoses[1] + 1;
}
else if (colonSize == 1)
{
size_t partLen = static_cast<size_t>(colonPoses[0] - spanStr);
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(spanStr, partLen, LLBC_TimeConst::numOfMicrosPerMinute);

secPart = colonPoses[0] + 1;
}
else
{
secPart = spanStr;
}

// - Parse <SS.micro_sec> part.
const char *dotPos = secPart;
while (dotPos != spanStrEnd)
{
if (*dotPos == '.')
break;

++dotPos;
}

const char *secPartEnd = dotPos != spanStrEnd ? dotPos : spanStrEnd;
size_t secPartLen = secPartEnd - secPart;
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(secPart, secPartLen, LLBC_TimeConst::numOfMicrosPerSecond);
if (dotPos != spanStrEnd)
{
size_t microPartLen = spanStrEnd - dotPos - 1;
__LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN(dotPos + 1, microPartLen, 1);
}
}

#undef __LLBC_INL_TIME_SPAN_STR_PART_TO_SPAN

__LLBC_NS_END
Loading

0 comments on commit 89a5f2b

Please sign in to comment.