QCborValueConstRef: optimize to{Integer,Bool,Double,String,ByteArray}()

The initial implementation from Qt 5.13 simply created a QCborValue and
then called the equivalent function on that result. For integrals and
double where the QCborValue matched the asked type, the cost was minimal
anyway. For the other types and when the type didn't match, this
resulted in up/down the reference counter in QCborContainerPrivate and
an out-of-line call to the destructor.

This improves the performance for code like:

  for (QCborValue v : array) {
      if (v.toString() == x) {
          doSomething();
      }
  }

Change-Id: I5e52dc5b093c43a3b678fffd16b6022da4e2d446
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Thiago Macieira 2021-11-29 10:33:16 -08:00
parent afe2f80c6a
commit f4d49910be
2 changed files with 61 additions and 5 deletions

View File

@ -2635,6 +2635,52 @@ void QCborValueRef::assign(QCborValueRef that, const QCborValueRef other)
that = other.concrete();
}
bool QCborValueConstRef::concreteBoolean(QCborValueConstRef self, bool defaultValue) noexcept
{
QtCbor::Element e = self.d->elements.at(self.i);
if (e.type != QCborValue::False && e.type != QCborValue::True)
return defaultValue;
return e.type == QCborValue::True;
}
double QCborValueConstRef::concreteDouble(QCborValueConstRef self, double defaultValue) noexcept
{
QtCbor::Element e = self.d->elements.at(self.i);
if (e.type == QCborValue::Integer)
return e.value;
if (e.type != QCborValue::Double)
return defaultValue;
return e.fpvalue();
}
qint64 QCborValueConstRef::concreteIntegral(QCborValueConstRef self, qint64 defaultValue) noexcept
{
QtCbor::Element e = self.d->elements.at(self.i);
QCborValue::Type t = e.type;
if (t == QCborValue::Double)
return e.fpvalue();
if (t != QCborValue::Integer)
return defaultValue;
return e.value;
}
QByteArray QCborValueConstRef::concreteByteArray(QCborValueConstRef self,
const QByteArray &defaultValue)
{
QtCbor::Element e = self.d->elements.at(self.i);
if (e.type != QCborValue::ByteArray)
return defaultValue;
return self.d->byteArrayAt(self.i);
}
QString QCborValueConstRef::concreteString(QCborValueConstRef self, const QString &defaultValue)
{
QtCbor::Element e = self.d->elements.at(self.i);
if (e.type != QCborValue::String)
return defaultValue;
return self.d->stringAt(self.i);
}
QCborValue QCborValueConstRef::concrete(QCborValueConstRef self) noexcept
{
return self.d->valueAt(self.i);

View File

@ -445,6 +445,16 @@ protected:
static Q_CORE_EXPORT QCborValue concrete(QCborValueConstRef that) noexcept;
static Q_CORE_EXPORT QCborValue::Type concreteType(QCborValueConstRef that) noexcept Q_DECL_PURE_FUNCTION;
static Q_CORE_EXPORT bool
concreteBoolean(QCborValueConstRef that, bool defaultValue) noexcept Q_DECL_PURE_FUNCTION;
static Q_CORE_EXPORT double
concreteDouble(QCborValueConstRef that, double defaultValue) noexcept Q_DECL_PURE_FUNCTION;
static Q_CORE_EXPORT qint64
concreteIntegral(QCborValueConstRef that, qint64 defaultValue) noexcept Q_DECL_PURE_FUNCTION;
static Q_CORE_EXPORT QByteArray
concreteByteArray(QCborValueConstRef that, const QByteArray &defaultValue);
static Q_CORE_EXPORT QString
concreteString(QCborValueConstRef that, const QString &defaultValue);
constexpr QCborValueConstRef() : d(nullptr), i(0) {} // this will actually be invalid
constexpr QCborValueConstRef(QCborContainerPrivate *dd, qsizetype ii)
@ -513,16 +523,16 @@ public:
{ return concrete().taggedValue(defaultValue); }
qint64 toInteger(qint64 defaultValue = 0) const
{ return concrete().toInteger(defaultValue); }
{ return concreteIntegral(*this, defaultValue); }
bool toBool(bool defaultValue = false) const
{ return concrete().toBool(defaultValue); }
{ return concreteBoolean(*this, defaultValue); }
double toDouble(double defaultValue = 0) const
{ return concrete().toDouble(defaultValue); }
{ return concreteDouble(*this, defaultValue); }
QByteArray toByteArray(const QByteArray &defaultValue = {}) const
{ return concrete().toByteArray(defaultValue); }
{ return concreteByteArray(*this, defaultValue); }
QString toString(const QString &defaultValue = {}) const
{ return concrete().toString(defaultValue); }
{ return concreteString(*this, defaultValue); }
QDateTime toDateTime(const QDateTime &defaultValue = {}) const
{ return concrete().toDateTime(defaultValue); }
#ifndef QT_BOOTSTRAPPED