QDateTime::fromString(): improve performance by 33%

getMaximum() and getMinimum(), called during parsing, create new
QDateTime instances, which on Linux end up calling mktime().
Making these static (for the common case of LocalTime spec)
improves performance dramatically, when parsing several date/times.

tests/benchmarks/corelib/tools/qdatetime/ (after fixing it to
actually parse a valid date/time) says:
 RESULT : tst_QDateTime::fromString():
-     36,742,060 instruction reads per iteration (total: 36,742,060, iterations: 1)
+     24,230,060 instruction reads per iteration (total: 24,230,060, iterations: 1)

Change-Id: I0c3931285475bf19a5be8cba1486ed07cbf5e134
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
David Faure 2017-03-03 14:06:49 +01:00
parent 9449325f2b
commit a8ae8e3130
2 changed files with 18 additions and 7 deletions

View File

@ -1216,15 +1216,15 @@ end:
} else {
if (context == FromString) {
// optimization
Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
Q_ASSERT(maximum.date().toJulianDay() == 4642999);
if (newCurrentValue.date().toJulianDay() > 4642999)
state = Invalid;
} else {
if (newCurrentValue > getMaximum())
if (newCurrentValue > maximum)
state = Invalid;
}
QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << minimum << maximum;
}
}
StateNode node;
@ -1607,13 +1607,13 @@ bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, in
bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QStringRef &text) const
{
Q_ASSERT(current >= getMinimum() && current <= getMaximum());
const SectionNode &node = sectionNode(index);
Q_ASSERT(text.size() < sectionMaxSize(index));
const QDateTime maximum = getMaximum();
const QDateTime minimum = getMinimum();
Q_ASSERT(current >= minimum && current <= maximum);
QDateTime tmp = current;
int min = absoluteMin(index);
setDigit(tmp, index, min);
@ -1713,11 +1713,21 @@ bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) con
QDateTime QDateTimeParser::getMinimum() const
{
// Cache the most common case
if (spec == Qt::LocalTime) {
static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, Qt::LocalTime);
return localTimeMin;
}
return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
}
QDateTime QDateTimeParser::getMaximum() const
{
// Cache the most common case
if (spec == Qt::LocalTime) {
static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, Qt::LocalTime);
return localTimeMax;
}
return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
}

View File

@ -547,8 +547,9 @@ void tst_QDateTime::currentMSecsSinceEpoch()
void tst_QDateTime::fromString()
{
QString format = "yyy-MM-dd hh:mm:ss.zzz t";
QString input = "2010-01-01 13:12:11.999 UTC";
QString format = "yyyy-MM-dd hh:mm:ss.zzz";
QString input = "2010-01-01 13:12:11.999";
QVERIFY(QDateTime::fromString(input, format).isValid());
QBENCHMARK {
for (int i = 0; i < 1000; ++i)
QDateTime::fromString(input, format);