Fix for DEV-39442: Increased the performance of LLDate::toHTTPDateString
by over 50 times. Looking at the usage, toHTTPDateStream is not called anywhere (except internally by toHTTPDateString), and toHTTPDateString is called only once outside of lldate.cpp, by LLStringUtil::formatDatetime. Also, the method is most commonly called with a single two-character token, such as "%Y" or "%A". I therefore removed toHTTPDateStream and optimized toHTTPDateString. Setting the locale was the most expensive operation, so I looked into caching that, both in terms of std::ostream and strftime. The timings for those implementations (averaged over 10 calls) is: toHTTPDateString timings: - with ostream (current) -> 0.314156 ms - with ostream and std::locale caching -> 0.033999 ms - with strftime and setlocale() caching -> 0.005985 ms I therefore went with the standard C library strftime solution. I also wrote a few unit tests to make sure that I didn't break any existing functionality, and tested this under Windows and Linux. Reviewed by steve.master
parent
bc106b1b4b
commit
f7231263d4
|
|
@ -38,7 +38,7 @@
|
|||
#include "apr_time.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <locale>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
|
@ -100,33 +100,28 @@ std::string LLDate::toHTTPDateString (std::string fmt) const
|
|||
{
|
||||
LLFastTimer ft1(FT_DATE_FORMAT);
|
||||
|
||||
std::ostringstream stream;
|
||||
time_t locSeconds = (time_t) mSecondsSinceEpoch;
|
||||
struct tm * gmt = gmtime (&locSeconds);
|
||||
|
||||
stream.imbue (std::locale(LLStringUtil::getLocale().c_str()));
|
||||
toHTTPDateStream (stream, gmt, fmt);
|
||||
return stream.str();
|
||||
return toHTTPDateString(gmt, fmt);
|
||||
}
|
||||
|
||||
std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
|
||||
{
|
||||
LLFastTimer ft1(FT_DATE_FORMAT);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream.imbue (std::locale(LLStringUtil::getLocale().c_str()));
|
||||
toHTTPDateStream (stream, gmt, fmt);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void LLDate::toHTTPDateStream(std::ostream& s, tm * gmt, std::string fmt)
|
||||
{
|
||||
LLFastTimer ft1(FT_DATE_FORMAT);
|
||||
// avoid calling setlocale() unnecessarily - it's expensive.
|
||||
static std::string prev_locale = "";
|
||||
std::string this_locale = LLStringUtil::getLocale();
|
||||
if (this_locale != prev_locale)
|
||||
{
|
||||
setlocale(LC_TIME, this_locale.c_str());
|
||||
prev_locale = this_locale;
|
||||
}
|
||||
|
||||
const char * pBeg = fmt.c_str();
|
||||
const char * pEnd = pBeg + fmt.length();
|
||||
const std::time_put<char>& tp = std::use_facet<std::time_put<char> >(s.getloc());
|
||||
tp.put (s, s, s.fill(), gmt, pBeg, pEnd);
|
||||
// use strftime() as it appears to be faster than std::time_put
|
||||
char buffer[128];
|
||||
strftime(buffer, 128, fmt.c_str(), gmt);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
void LLDate::toStream(std::ostream& s) const
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ public:
|
|||
void toStream(std::ostream&) const;
|
||||
std::string toHTTPDateString (std::string fmt) const;
|
||||
static std::string toHTTPDateString (tm * gmt, std::string fmt);
|
||||
static void toHTTPDateStream(std::ostream&, tm *, std::string);
|
||||
/**
|
||||
* @brief Set the date from an ISO-8601 string.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue