Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit 27c8cf46 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère
Browse files

Simplified meta() to lower its cost when not used

Run bench
parent 02645b25
......@@ -82,33 +82,26 @@ static QIdentifierLiteral qBindIgnoredBytes ("IgnoredBytes" );
#include <QtCore/qstring.h>
//! QMetaData is optional data about current data to enable optimized processing (e.g. tag, , style, etc.) and/or transmission (QAbstractItemModel headers, CBOR tags, XML attribute, CSS, numpy.ndarray shapes, etc.)
class QMetaData : public std::vector<std::pair<QIdentifierLiteral,QAsciiData>>
{
public:
using vector::vector;
iterator find(QIdentifierLiteral n) { return std::find_if(begin(), end(), [n](std::pair<QIdentifierLiteral,QAsciiData>& item){ return item.first==n; }); }
QAsciiData& operator[](QIdentifierLiteral n) { return find(n)->second; }
};
// meta(QIdentifierLiteral name, QAsciiData value) is optional meta-data about current data to enable optimized processing (e.g. tag, , style, etc.) and/or transmission (QAbstractItemModel headers, CBOR tags, XML attribute, CSS, numpy.ndarray shapes, etc.)
static QIdentifierLiteral qmDataStreamVersion("qmDataStreamVersion"); //!< Allows IBind support of QDataStream
static const QIdentifierLiteral qmDataStreamVersion("qmDataStreamVersion"); //!< Allows IBind support of QDataStream
// N-dimensional data structures for which specific IWriter may have optimized implementations
// BEWARE though that nested calls to IWriter are not guaranteed to follow the declared structure (this would prevent reusing general QBind functors for nested data structures)
//! Sequence of records can be implemented as table with columns below (record item names are always the same in a fixed order)
static QIdentifierLiteral qmColumns ("columns" ); //!< comma-separated names
static const QIdentifierLiteral qmColumns ("columns" ); //!< comma-separated names
//! Sequence of nested non-empty sequences of definite sizes can be implemented as multi-dimensional array
static QIdentifierLiteral qmSizes ("sizes" ); //!< comma-separated natural numbers
static const QIdentifierLiteral qmSizes ("sizes" ); //!< comma-separated natural numbers
//! Sequence of records where item(qmNodes) contains children can be implemented as trees
static QIdentifierLiteral qmChildren("children"); //!< name of a sequence of records with recursively the same name
static const QIdentifierLiteral qmChildren("children"); //!< name of a sequence of records with recursively the same name
//! Name of current data
static QIdentifierLiteral qmName ("name" );
static const QIdentifierLiteral qmName ("name" );
static QIdentifierLiteral qmColor ("color" ); //!< comma-separated names
static const QIdentifierLiteral qmColor ("color" ); //!< comma-separated names
// //////////////////////////////////////////////////////////////////////////
// QBind<T,TResult>
......@@ -177,7 +170,7 @@ public:
operator bool() noexcept { return outer.operator bool(); } //!< Drives QBind<T>::bind() traversal
TResult* operator->() noexcept { return outer.operator ->(); }
/**/ Val<T_> meta ( QMetaData& m) { outer->_meta(m); return std::move(*this); }
/**/ Val<T_> meta (QIdentifierLiteral& n, QAsciiData& m) { outer->_meta(n,m); return std::move(*this); }
/**/ Seq<T_> sequence(quint32* s=nullptr) { return outer->_sequence (s) ? Seq<T_>(std::move(outer)) : Seq<T_>(); }
/**/ Rec<T_> record (quint32* s=nullptr) { return outer->_record (s) ? Rec<T_>(std::move(outer)) : Rec<T_>(); }
......@@ -196,15 +189,17 @@ public:
template<typename T> T_ with (T& t, QBindFunction<T> customBind) { return customBind(t, std::move(unsafeThis())) ? std::move(outer) : T_(); }
// Literal metadata support
/**/ Val<T_> meta(QIdentifierLiteral n, QAsciiData m) { return meta({{n,m}}); }
/**/ Val<T_> meta(const char* n, QAsciiData m) { return meta({{QIdentifierLiteral(n),m}}); }
/**/ Val<T_> meta (QMetaData&& m) { return meta ( m); }
/**/ Seq<T_> sequence( quint32 s) { return sequence(&s); }
/**/ Rec<T_> record ( quint32 s) { return record (&s); }
Val<T_> meta( QIdentifierLiteral&& n, QAsciiData&& m) { QIdentifierLiteral nref=n; QAsciiData mref=m; return meta(nref, mref); }
Val<T_> meta(const QIdentifierLiteral& n, QAsciiData&& m) { QIdentifierLiteral nref=n; QAsciiData mref=m; return meta(nref, mref); }
Val<T_> meta(const QIdentifierLiteral& n, const char* m) { QIdentifierLiteral nref=n; QAsciiData mref=QAsciiData(m); return meta(nref, mref); }
Val<T_> meta( QIdentifierLiteral&& n, const QAsciiData& m) { QIdentifierLiteral nref=n; QAsciiData mref=m; return meta(nref, mref); }
Val<T_> meta(const char* n, const char* m) { return meta(QIdentifierLiteral(n),QAsciiData(m)); }
Seq<T_> sequence( quint32 s) { return sequence(&s); }
Rec<T_> record ( quint32 s) { return record (&s); }
// Shortcuts
template<typename T> Seq<T_> operator<<( T&& t) { return sequence().bind(std::forward<T>(t)); } // stream compatible
/**/ Rec<T_> record(const char* n) { return meta({{qmName,QAsciiData(n)}}).record(); }
/**/ Rec<T_> record(const char* n) { return meta(qmName,QAsciiData(n)).record(); }
private:
Val<TResult> unsafeThis() noexcept { return Val<TResult>(outer->_unsafeCopy()); }
......@@ -346,15 +341,16 @@ protected:
template<class T_> friend class Seq;
template<class T_> friend class Rec;
void _meta ( QMetaData& d) { if (Q_LIKELY(impl) ) impl->_meta (d); } //!< idempotent (can be called by more than one code)
bool _sequence(quint32* s=nullptr) { return Q_LIKELY(impl) && impl->_sequence(s); }
bool _record (quint32* s=nullptr) { return Q_LIKELY(impl) && impl->_record (s); }
bool _null ( ) { return Q_LIKELY(impl) && impl->_null ( ); }
bool _any ( ) { return Q_LIKELY(impl) && impl->_any ( ); }
bool _bind ( QUtf8DataView u) { return Q_LIKELY(impl) && impl->_bind (u); }
bool _bind ( QAsciiDataView a) { return Q_LIKELY(impl) && impl->_bind (a); }
bool _bind ( QLatin1String l) { return Q_LIKELY(impl) && impl->_bind (l); }
bool _bind ( QStringView u) { return Q_LIKELY(impl) && impl->_bind (u); }
void _meta (QIdentifierLiteral& n,
QAsciiData& m) { if (Q_LIKELY(impl) ) impl->_meta (n,m); } //!< idempotent (can be called by more than one code)
bool _sequence( quint32* s=nullptr) { return Q_LIKELY(impl) && impl->_sequence(s); }
bool _record ( quint32* s=nullptr) { return Q_LIKELY(impl) && impl->_record (s); }
bool _null ( ) { return Q_LIKELY(impl) && impl->_null ( ); }
bool _any ( ) { return Q_LIKELY(impl) && impl->_any ( ); }
bool _bind ( QUtf8DataView u) { return Q_LIKELY(impl) && impl->_bind (u); }
bool _bind ( QAsciiDataView a) { return Q_LIKELY(impl) && impl->_bind (a); }
bool _bind ( QLatin1String l) { return Q_LIKELY(impl) && impl->_bind (l); }
bool _bind ( QStringView u) { return Q_LIKELY(impl) && impl->_bind (u); }
template<typename T> bool _bind( T&& t) { return _bind(BindSupport<RemoveCvRef<T>,TImpl>() ,std::forward<T>(t)); }
private:
......@@ -467,8 +463,8 @@ struct IBind {
virtual bool _any() { return _null(); }
//! \warning QMetaData is ignored by default and subject to various interpretation, so users should define or adopt existing meta data standards like XSD for sake of interoperability
virtual void _meta(QMetaData&) {}
//! \warning meta() is ignored by default and subject to various interpretation, so users should define or adopt existing meta data standards like XSD for sake of interoperability
virtual void _meta(QIdentifierLiteral&, QAsciiData&) {}
virtual void _setChoice(bool) {}
virtual void _reportError(QIdentifierLiteral) {}
......@@ -890,9 +886,9 @@ TResult qbind(Val<TResult>&& v, T* t) {
auto i = r.item(id);
if (p.isEnumType()) {
pv.convert(QVariant::Int);
i = i.meta({{qmName, p.isFlagType() ?
QAsciiData(p.enumerator().valueToKeys(pv.value<int>())) :
QAsciiData(p.enumerator().valueToKey (pv.value<int>()))}});
i = i.meta(qmName, p.isFlagType() ?
QAsciiData(p.enumerator().valueToKeys(pv.value<int>())) :
QAsciiData(p.enumerator().valueToKey (pv.value<int>())));
}
r = i.bind(pv);
}
......
......@@ -100,7 +100,7 @@ enum {
// //////////////////////////////////////////////////////////////////////////
// QBind<T,QCbor*> support
class QCborWriter : public IWriter // TODO Support CBOR tags for IBind BindNative types and multi-dimensional QMetaData (e.g. support qmColumns with http://cbor.schmorp.de/stringref, qmSizes with https://datatracker.ietf.org/doc/draft-ietf-cbor-array-tags/?include_text=1 )
class QCborWriter : public IWriter // TODO Support CBOR tags for IBind BindNative types and multi-dimensional meta() (e.g. support qmColumns with http://cbor.schmorp.de/stringref, qmSizes with https://datatracker.ietf.org/doc/draft-ietf-cbor-array-tags/?include_text=1 )
{
Q_DISABLE_COPY(QCborWriter)
public:
......@@ -109,7 +109,6 @@ public:
// Shortcuts
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta(m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence(s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
......@@ -187,7 +186,6 @@ public:
// Shortcuts
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta(m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence(s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
......@@ -298,7 +296,6 @@ public:
// Shortcuts
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta(m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence(s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
......
......@@ -52,8 +52,8 @@
// TODO Use QByteArray directly
//! \warning As with QDataStream, QDataWriter and QDataReader must bind compatible C++ data types, and QDataStream ByteOrder, FloatingPointPrecision and Version
//! \remark When not statically known, such information can be transmitted using meta({{"type",...}}) although some IBind implementations may not support it
class QDataWriter : public IWriter // allows runtime flexibility but requires QBind<T> in addition to T::operator<<(QDataStream&) and does not warrant QDataStream operators compatibility if QBind<T> ignores qmDataStreamVersion in meta(QMetaData&)
//! \remark When not statically known, such information can be transmitted using meta("type",...) although some IBind implementations may not support it
class QDataWriter : public IWriter // allows runtime flexibility but requires QBind<T> in addition to T::operator<<(QDataStream&) and does not warrant QDataStream operators compatibility if QBind<T> ignores qmDataStreamVersion in meta()
{
Q_DISABLE_COPY(QDataWriter)
public:
......@@ -63,7 +63,6 @@ public:
// Shortcuts
Val<Cur<QDataWriter>> value ( ) { return Cur<QDataWriter>(this).value(); }
Val<Cur<QDataWriter>> meta ( QMetaData&& m) { return Cur<QDataWriter>(this).value().meta(m); }
Seq<Cur<QDataWriter>> sequence(quint32* s=nullptr) { return Cur<QDataWriter>(this).value().sequence(s); }
template<typename T> Cur<QDataWriter> bind(T&& t) { return Cur<QDataWriter>(this).value().bind(std::forward<T>(t)); }
......@@ -83,7 +82,7 @@ protected:
bool _item(QIdentifier& ) { return true; } // record keys are implicit, maps should be serialized as a sequence of records with key and value items
bool _item(QIdentifierLiteral) { return true; } // for QBaseWriter
void _meta(QMetaData& m) { m[qmDataStreamVersion]=version; }
void _meta(QIdentifierLiteral& n, QAsciiData& m) { if (n == qmDataStreamVersion) m=version; }
private:
QDataStream* io;
QAsciiData version;
......@@ -96,4 +95,4 @@ template<typename T> struct BindSupport<T ,QDataWriter> : BindNative {}; //!
// \remark Providing a general QDataReader may be deceiving because the QDataStream structure is implicit, thus
// a reader is usually assumed to statically know the data type to read based on the stream origin and version.
// Though QVariant can be used for parts which type are not statically known though, such as the dynamic type of a message coming from a socket.
// Finally, QDataStream version can be retrieved from meta(QMetaData&) to adapt to data schema changes over the time \see QBind<QColor> for an example
// Finally, QDataStream version can be retrieved from meta() to adapt to data schema changes over the time \see QBind<QColor> for an example
......@@ -65,38 +65,38 @@ class QModelWriter : public IWriter
public:
QModelWriter(QAbstractItemModel* m, bool rowFirst=true) : m(m), rowFirst(rowFirst), w(&io) { Q_ASSERT(m); }
Seq<Cursor> sequence( ) { return Cursor(this).value().sequence(); }
Val<Cursor> meta (QMetaData&& m) { return Cursor(this).value().meta(m); }
Val<Cursor> value () { return Cursor(this).value(); }
Seq<Cursor> sequence() { return Cursor(this).value().sequence(); }
protected:
void _meta(QMetaData& meta) {
void _meta(QIdentifierLiteral& n, QAsciiData& meta) {
if (T==d) {
if (meta.find(qmChildren)!=meta.end()) {
childrenName = QIdentifier(meta[qmChildren].latin1());
if (n == qmChildren) {
childrenName = QIdentifier(meta.latin1());
}
if (meta.find(qmColumns)!=meta.end()) {
if (n == qmColumns) {
metaColumnNames=true;
int i=0;
for (auto&& k : meta[qmColumns].utf8().split(',')) {
for (auto&& k : meta.utf8().split(',')) {
m->insertColumn(i);
m->setHeaderData(i,Qt::Horizontal,k);
columnNames.insert(i,k);
i++;
}
}
if (meta.find(qmSizes)!=meta.end()) {
for (auto&& k : meta[qmSizes].utf8().split(',')) {
if (n == qmSizes) {
for (auto&& k : meta.utf8().split(',')) {
int i = k.toInt();
if (0<i) sizes.append(i);
}
}
}
else if (C==d) {
if (meta.find(qmColor)!=meta.end()) {
m->setData(current(),QColor(meta[qmColor].latin1()),Qt::ForegroundRole);
if (n == qmColor) {
m->setData(current(),QColor(meta.latin1()),Qt::ForegroundRole);
}
}
else {
w._meta(meta);
w._meta(n, meta);
}
}
......@@ -275,7 +275,7 @@ private:
QModelIndex parent;
int row=0, col=0; //!< Allows handling {null} equally to {} (but not equally to null) without requiring QModelIndex to reference rows/columns before they actually exist
// Supported QMetaData
// Supported meta()
QIdentifier childrenName;
QList<QByteArray> columnNames;
bool metaColumnNames=false;
......
......@@ -68,7 +68,6 @@ public:
// Shortcuts
Val<Cursor> value ( ) { return Cursor(this).value(); }
Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta(m); }
Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence(s); }
template<typename T> Cursor bind(T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
......@@ -91,28 +90,37 @@ protected:
bool _out ( ) { io->writeEndElement(); return true; }
bool _item( ) { return true; }
bool _item(QIdentifier& n) { name=n; return true; }
void _meta(QMetaData& m) {
for (auto&& kv : m) {
if (kv.first == qmName) {
name = QIdentifier(kv.second.utf8());
}
else {
auto found = metaData.find(kv.first);
if (found!=metaData.end()) {
found->second = kv.second;
}
else {
metaData.push_back(kv);
}
}
}
}
void _meta(QIdentifierLiteral &n, QAsciiData &m);
private:
class Atts : public std::vector<std::pair<QIdentifierLiteral,QAsciiData>>
{
public:
using vector::vector;
iterator find(QIdentifierLiteral n) { return std::find_if(begin(), end(), [n](std::pair<QIdentifierLiteral,QAsciiData>& item){ return item.first==n; }); }
QAsciiData& operator[](QIdentifierLiteral n) { return find(n)->second; }
};
void writeText(const char* def, QString text) { io->writeStartElement(tag(def).latin1()); att(); io->writeCharacters(text); io->writeEndElement(); }
QIdentifier tag(const char* def) { if (name.isNull()) { return QIdentifier(def); } auto n=name; name=QIdentifier(); return n; }
void att() { for (auto&& a : metaData) { if (!a.second.isNull()) io->writeAttribute(a.first.latin1(), a.second.latin1()); } }
void att() { for (auto&& a : atts) { if (!a.second.isNull()) io->writeAttribute(a.first.latin1(), a.second.latin1()); } }
QXmlStreamWriter* io;
QMetaData metaData;
Atts atts;
QIdentifier name;
};
void QXmlWriter::_meta(QIdentifierLiteral& n, QAsciiData& m) {
if (n == qmName) {
name = QIdentifier(m.utf8());
}
else {
auto found = atts.find(n);
if (found != atts.end()) {
found->second = m;
}
else {
atts.push_back(std::make_pair(n,m));
}
}
}
......@@ -129,13 +129,13 @@ QDataStream &operator>>(QDataStream &in, Person &p)
return in >> p.firstName >> p.lastName >> p.height >> p.age >> p.phones >> p.comments >> p.children;
}
// Using inheritance to complement an existing bind with QMetaData
// Using inheritance to complement an existing bind with meta()
struct Persons : public QVector<Person> {
Cursor bind(Val<Cursor>&& value) {
return value
.meta({{qmChildren,QAsciiData(QByteArrayLiteral("children" ))}
,{qmColumns ,QAsciiData(QByteArrayLiteral("names,height,age,phones,comments"))}}) // to optimize multi-dimensional data formats
.meta(qmChildren,"children" )
.meta(qmColumns ,"names,height,age,phones,comments") // to optimize multi-dimensional data formats
.bind(static_cast<QVector<Person>>(*this))
;
}
......@@ -146,7 +146,7 @@ struct Persons : public QVector<Person> {
#include <QtGui/qcolor.h>
//! QBind<QColor,_> with special support for QDataStream compatibility using QMetaData
//! QBind<QColor,_> with special support for QDataStream compatibility using meta()
template<>
struct QBind<QColor> {
static Cursor bind(Val<Cursor>&& v, QColor&& c) {
......@@ -157,15 +157,17 @@ struct QBind<QColor> {
if (!c.isValid()) {
return v.null();
}
QMetaData m;
v=v.meta(m);
auto dataStreamVersion = m.find(qmDataStreamVersion);
if (dataStreamVersion!=m.end()) {
if (dataStreamVersion->second.utf8().toInt()<7) { v->reportError("UnsupportedQDataStreamVersion");
return v.null();
QIdentifierLiteral n;
QAsciiData m;
do {
v=v.meta(n, m);
if (n==qmDataStreamVersion) {
if (m.utf8().toInt()<7) { v->reportError("UnsupportedQDataStreamVersion");
return v.null();
}
return v.sequence().bind(qint8(c.spec())).bind(quint16(c.alpha())).bind(quint16(c.cyan())).bind(quint16(c.magenta())).bind(quint16(c.yellow())).bind(quint16(c.black()));
}
return v.sequence().bind(qint8(c.spec())).bind(quint16(c.alpha())).bind(quint16(c.cyan())).bind(quint16(c.magenta())).bind(quint16(c.yellow())).bind(quint16(c.black()));
}
} while (!n.isNull());
Rec<Cursor> r = v.record();
switch(c.spec()) {
case QColor::Spec::Rgb : r = r.sequence("RGB" ).bind(quint8(c.red ())).bind(quint8(c.green ())).bind(quint8(c.blue ())) .out(); break;
......@@ -207,7 +209,7 @@ protected:
bool _item( ) { utf8->append(" ") ; return true; }
bool _out ( ) { utf8->append("]") ; return true; }
void _meta(QMetaData& m) { bool isFirst=true; for (auto kv: m) { utf8->append(isFirst?"(":" "); isFirst=false; if (kv.first!=qmName) { utf8->append(kv.first.utf8(), kv.first.size()).append(":"); } utf8->append(kv.second.utf8()); } if (!isFirst) { utf8->append(")"); } }
void _meta(QIdentifierLiteral& n, QAsciiData& m) { if (n==qmName) utf8->append('(').append(m.utf8()).append(")"); }
private:
QByteArray* utf8;
};
......@@ -1018,9 +1020,10 @@ void doGuiExample() {
QStandardItemModel matrixModel, treeModel, tableModel, customModel, flatModel;
// Using meta() to drive various custom bind
QModelWriter<>(&matrixModel,false).meta({{qmSizes ,QAsciiData(QByteArrayLiteral("4,3" ))} }).bind(transform);
QModelWriter<>(& treeModel ).meta({{qmChildren,QAsciiData(QByteArrayLiteral("children"))}/*,{qmColumns ,"names,age"}*/}).bind(persons);
QModelWriter<>(& tableModel ).meta({{qmColumns ,QAsciiData(QByteArrayLiteral( "names,age"))} }).bind(persons);
QModelWriter<>(&matrixModel,false).value().meta(qmSizes ,"4,3" ).bind(transform);
QModelWriter<>(& treeModel ).value().meta(qmChildren,"children" )
/*.meta(qmColumns ,"names,age")*/.bind(persons);
QModelWriter<>(& tableModel ).value().meta(qmColumns ,"names,age") .bind(persons);
// Various possible designs for flexible custom bind
#if 0
......@@ -1038,12 +1041,12 @@ void doGuiExample() {
});
#else
// More expressive design similar to Python list comprehensions that does not work by default for Read/Write
QModelWriter<>(&customModel).sequence().with([&](Seq<Cursor>&& s) { // See https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this
QModelWriter<>(&customModel).sequence().with([&](Seq<Cursor>&& s) {
for (auto&& person : persons) { // Read would require looping while !s.item()
s = s // To keep working with the active Cursor
.record()
.item("first name")
.meta(qmColor, QAsciiData(person.age >= 42 ? "green" : "blue"))
.meta(qmColor, person.age >= 42 ? "green" : "blue")
.bind(person.firstName)
.item("office phone").with([&](Val<Cursor>&& v) {
for (auto&& phone : person.phones) {
......
============| QDebug| Text| Json| Xml| Variant| Cbor| QCborStream| Data| QDataStream| QByteArray| Bindables|Bindables>Cbor|Bindables>Json|total(usecs)|variation(%)
builtin> | 15.5| 6.8| 16.0| 93.2| 18.1| 2.4| 3.9| 2.6| 1.4| 0.4| 0.3| 2.6| 16.2| 179.4| 19.4
builtin> | 16.2| 21.4| 15.6| 71.0| 16.5| 2.6| 4.7| 4.9| 3.7| 0.4| 0.3| 4.0| 154.6| 315.8| 76.0
builtin> | 15.2| 6.6| 15.3| 67.0| 18.3| 2.6| 4.2| 2.9| 1.4| 0.4| 0.2| 2.5| 15.0| 151.4| 52.1
builtin> | 14.5| 6.2| 15.1| 68.8| 20.7| 2.6| 4.0| 2.8| 1.5| 0.4| 0.3| 2.8| 16.1| 155.7| 2.8
builtin> | 14.9| 6.5| 15.3| 202.1| 16.3| 2.5| 4.0| 2.9| 1.5| 0.4| 0.3| 2.8| 16.4| 285.8| 83.5
builtin> | 23.3| 6.3| 16.0| 205.3| 20.1| 2.7| 4.6| 3.0| 1.8| 0.4| 0.3| 3.0| 17.4| 304.1| 6.4
builtin> | 131.7| 7.0| 23.1| 70.9| 16.8| 2.6| 4.3| 2.8| 1.6| 0.4| 0.3| 2.8| 16.6| 280.8| 7.7
builtin> | 14.7| 6.8| 23.6| 88.7| 26.1| 2.8| 4.7| 3.4| 1.4| 0.4| 0.3| 2.8| 22.0| 197.5| 29.7
builtin> | 27.3| 6.9| 21.7| 124.0| 119.8| 2.4| 4.6| 3.2| 1.7| 0.3| 0.2| 2.7| 22.0| 336.7| 70.5
builtin> | 31.3| 35.5| 86.1| 108.8| 22.6| 10.6| 11.2| 4.0| 2.1| 0.5| 0.4| 3.6| 22.7| 339.3| 0.8
builtin> | 24.0| 12.6| 23.2| 194.2| 49.2| 4.1| 9.9| 11.2| 10.9| 1.3| 0.3| 4.1| 60.5| 405.6| 19.5
============| QDebug| Text| Json| Xml| Variant| Cbor| QCborStream| Data| QDataStream| QByteArray| Bindable| Bindable>Cbor| Bindable>Json|total(usecs)|variation(%)
doubles> | 72.7| 44.2| 48.1| 251.8| 16.2| 3.2| 4.1| 4.0| 4.0| 1.4| 0.1| 5.8| 72.5| 528.1| 7.6
doubles> | 41.3| 65.3| 53.4| 215.6| 17.9| 3.3| 4.1| 3.8| 3.5| 1.2| 0.1| 3.4| 40.0| 452.9| 14.2
doubles> | 69.7| 42.8| 51.7| 181.9| 14.3| 2.8| 3.5| 3.4| 2.7| 1.0| 0.1| 3.0| 49.2| 426.0| 5.9
doubles> | 46.4| 38.0| 42.4| 147.6| 13.9| 2.8| 3.5| 3.4| 2.4| 0.9| 0.0| 2.5| 33.4| 337.4| 20.8
doubles> | 32.1| 40.3| 47.9| 196.6| 24.2| 7.2| 7.7| 6.9| 3.0| 0.9| 0.0| 6.4| 52.0| 425.2| 26.0
doubles> | 44.3| 34.6| 36.0| 157.0| 13.9| 2.8| 3.3| 3.2| 2.4| 0.9| 0.0| 2.8| 33.6| 334.8| 21.3
doubles> | 43.7| 29.2| 35.7| 116.0| 13.2| 2.4| 4.8| 2.9| 2.2| 0.8| 0.0| 2.4| 32.9| 286.1| 14.5
doubles> | 28.0| 26.8| 33.1| 120.9| 13.5| 2.5| 4.0| 4.8| 2.5| 0.8| 0.0| 2.4| 31.7| 271.1| 5.2
doubles> | 29.6| 26.5| 35.0| 120.2| 13.5| 3.4| 3.5| 2.9| 2.3| 0.8| 0.0| 2.4| 32.1| 272.4| 0.5
doubles> | 28.8| 27.2| 32.4| 122.7| 14.4| 2.6| 3.2| 3.1| 2.4| 0.9| 0.0| 2.5| 33.8| 274.0| 0.6
============| QDebug| Text| Json| Xml| Variant| Cbor| QCborStream| Data| QDataStream| QByteArray| Bindable| Bindable>Cbor| Bindable>Json|total(usecs)|variation(%)
Person> | 19.2| 15.5| 27.9| 77.5| 20.2| 8.1| 9.3| 2.4| 2.0| 0.5| 0.0| 7.3| 28.2| 218.3| 15.7
Person> | 21.5| 14.1| 27.5| 78.6| 19.1| 6.2| 8.6| 2.4| 1.6| 0.5| 0.0| 6.4| 30.6| 217.2| 0.5
Person> | 18.5| 11.6| 27.8| 77.5| 17.3| 6.2| 8.3| 2.2| 1.4| 0.5| 0.0| 17.6| 25.1| 214.0| 1.4
============| QDebug| Text| Json| Xml| Variant| Cbor| QCborStream| Data| QDataStream| QByteArray| Bindable| Bindable>Cbor| Bindable>Json|total(usecs)|variation(%)
Phone> | 5.0| 10.4| 15.3| 28.4| 11.7| 10.2| 2.9| 1.3| 0.6| 1.0| 0.1| 11.5| 14.8| 113.2| 8.8
Phone> | 4.9| 9.8| 14.1| 35.9| 11.7| 12.8| 2.9| 1.3| 0.6| 1.0| 0.0| 18.7| 15.7| 129.6| 14.5
Phone> | 4.9| 10.5| 15.3| 27.5| 11.3| 9.7| 2.8| 2.9| 0.6| 135.4| 0.0| 12.6| 15.3| 248.8| 92.0
Phone> | 5.2| 11.1| 15.3| 29.1| 11.0| 10.0| 2.9| 1.3| 0.6| 1.0| 0.0| 10.0| 40.8| 138.4| 44.4
Phone> | 5.2| 11.0| 15.2| 28.9| 11.6| 10.0| 2.9| 1.3| 0.6| 1.0| 0.0| 10.6| 17.1| 115.5| 16.6
Phone> | 5.2| 11.0| 15.2| 28.7| 11.5| 10.5| 2.9| 1.3| 0.6| 1.0| 0.0| 10.7| 16.0| 114.8| 0.6
Phone> | 5.1| 15.2| 25.0| 40.4| 15.6| 43.0| 3.3| 1.3| 0.6| 1.0| 0.0| 10.7| 15.4| 176.6| 53.9
============| Json>P| P>Json| Json>P| P>JsonValue| JsonValue>P|Json>JsonValue| Json>Cbor|total(usecs)|variation(%)
Person<>Json| 60.7| 15.2| 45.8| 28.5| 9.7| 57.8| 50.0| 267.7| 4.3
Person<>Json| 75.0| 37.1| 50.8| 27.4| 9.6| 59.5| 49.2| 308.5| 15.2
Person<>Json| 57.5| 15.7| 67.3| 27.2| 9.9| 58.3| 50.6| 286.4| 7.2
Person<>Json| 57.2| 16.1| 44.2| 29.1| 9.9| 63.3| 46.9| 266.7| 6.9
Person<>Json| 51.5| 17.6| 45.3| 29.4| 9.5| 99.8| 51.9| 304.9| 14.3
Person<>Json| 56.4| 17.1| 46.6| 54.7| 10.2| 61.0| 91.5| 337.6| 10.7
Person<>Json| 69.3| 31.9| 62.9| 34.5| 283.6| 59.8| 49.9| 592.0| 75.4
Person<>Json| 52.2| 15.6| 44.4| 28.2| 9.7| 56.4| 139.4| 346.0| 41.6
Person<>Json| 50.9| 16.2| 42.4| 30.6| 10.0| 57.6| 62.9| 270.7| 21.8
Person<>Json| 50.3| 15.7| 42.9| 27.7| 9.6| 57.3| 47.6| 251.2| 7.2
Person<>Json| 51.2| 15.9| 43.2| 27.6| 9.6| 57.0| 64.9| 269.3| 7.2
Person<>Json| 51.1| 14.8| 68.0| 38.7| 13.5| 107.9| 77.0| 371.1| 37.8
Person<>Json| 52.0| 15.7| 43.4| 28.7| 9.9| 381.6| 92.2| 623.5| 68.0
Person<>Json| 54.5| 63.3| 253.9| 115.4| 13.7| 102.8| 76.3| 679.9| 9.0
Person<>Json| 62.5| 19.0| 47.7| 53.3| 15.8| 62.1| 420.5| 681.0| 0.2
Person<>Json| 117.1| 17.8| 358.2| 32.4| 11.6| 76.8| 51.9| 665.8| 2.2
============| Cbor>P| P>Cbor| Cbor>P| QCborStream>P| P>CborValue| CborValue>P|Cbor>CborValue|CborValue>Cbor| Cbor>Json|total(usecs)|variation(%)
Person<>Cbor| 37.2| 8.1| 39.8| 17.9| 246.6| 11.1| 56.1| 20.2| 37.5| 474.5| 39.6
Person<>Cbor| 34.0| 7.5| 38.2| 16.4| 24.8| 10.8| 64.9| 18.9| 33.2| 248.7| 47.6
Person<>Cbor| 32.7| 7.2| 43.4| 18.9| 25.5| 10.1| 51.1| 18.8| 37.0| 244.6| 1.7
Person<>Cbor| 33.9| 8.2| 38.6| 17.8| 23.9| 10.4| 48.0| 19.0| 36.3| 236.1| 3.5
Person<>Cbor| 43.8| 9.5| 49.0| 20.7| 30.3| 11.8| 60.2| 18.1| 37.7| 281.1| 19.1
Person<>Cbor| 40.0| 8.3| 40.4| 17.6| 24.2| 10.6| 63.5| 21.9| 59.4| 285.8| 1.7
Person<>Cbor| 61.2| 10.7| 55.2| 25.1| 75.0| 13.6| 313.6| 20.2| 33.8| 608.3|112.8
Person<>Cbor| 33.4| 7.1| 37.9| 17.0| 23.9| 10.2| 50.3| 19.0| 34.4| 233.2| 61.7
Person<>Cbor| 33.7| 7.5| 47.4| 17.9| 24.3| 10.0| 64.4| 23.7| 45.6| 274.6| 17.7
Person<>Cbor| 33.0| 7.8| 37.6| 17.2| 23.9| 10.9| 51.1| 19.2| 36.7| 237.4| 13.5
Person<>Cbor| 33.6| 7.1| 37.3| 17.4| 25.2| 10.5| 51.0| 24.7| 42.6| 249.4| 5.1
Person<>Cbor| 32.6| 6.5| 42.5| 20.5| 25.5| 11.2| 59.3| 18.6| 33.4| 250.2| 0.3
Person<>Cbor| 32.9| 7.0| 36.8| 17.0| 22.4| 10.3| 47.9| 18.3| 33.9| 226.6| 9.4
============| P>Settings| Settings>P| P>Settings|total(usecs)|variation(%)
Person<>Settings| 804.8| 2.3| 26.3| 833.4| 28.1
Person<>Settings| 818.0| 2.3| 25.0| 845.3| 1.4
Person<>Settings| 897.5| 2.3| 23.9| 923.7| 9.3
Person<>Settings| 767.7| 2.1| 22.6| 792.5| 14.2
Person<>Settings| 637.0| 2.1| 23.5| 662.7| 16.4
Person<>Settings| 617.2| 2.3| 44.2| 663.7| 0.2
Person<>Settings| 629.1| 2.3| 23.1| 654.5| 1.4
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment