Use QByteArray instead of QString where possible for performance reasons

This commit is contained in:
Martin Tůma 2024-10-06 12:45:04 +02:00
parent e889815402
commit 497aa2e023
4 changed files with 53 additions and 35 deletions

View File

@ -31,12 +31,12 @@ static QVariant value(const vector_tile::Tile_Value &val)
else if (val.has_double_value())
return QVariant(val.double_value());
else if (val.has_string_value())
return QVariant(QString::fromStdString(val.string_value()));
return QVariant(QByteArray::fromStdString(val.string_value()));
else
return QVariant();
}
const QVariant *PBF::Feature::value(const QString &key) const
const QVariant *PBF::Feature::value(const QByteArray &key) const
{
const KeyHash &keys(_layer->keys());
KeyHash::const_iterator it(keys.find(key));
@ -92,7 +92,7 @@ PBF::Layer::Layer(const vector_tile::Tile_Layer *data) : _data(data)
{
_keys.reserve(data->keys_size());
for (int i = 0; i < data->keys_size(); i++)
_keys.insert(QString::fromStdString(data->keys(i)), i);
_keys.insert(QByteArray::fromStdString(data->keys(i)), i);
_values.reserve(data->values_size());
for (int i = 0; i < data->values_size(); i++)
_values.append(value(data->values(i)));
@ -107,7 +107,8 @@ PBF::PBF(const vector_tile::Tile &tile)
{
for (int i = 0; i < tile.layers_size(); i++) {
const vector_tile::Tile_Layer &layer = tile.layers(i);
_layers.insert(QString::fromStdString(layer.name()), new Layer(&layer));
_layers.insert(QByteArray::fromStdString(layer.name()),
new Layer(&layer));
}
}

View File

@ -8,7 +8,7 @@
#include "vector_tile.pb.h"
typedef QHash<QString, google::protobuf::uint32> KeyHash;
typedef QHash<QByteArray, google::protobuf::uint32> KeyHash;
class PBF
{
@ -22,7 +22,7 @@ public:
Feature(const vector_tile::Tile_Feature *data, const Layer *layer)
: _data(data), _layer(layer) {}
const QVariant *value(const QString &key) const;
const QVariant *value(const QByteArray &key) const;
vector_tile::Tile_GeomType type() const {return _data->type();}
QPainterPath path(const QSizeF &factor) const;
@ -55,10 +55,10 @@ public:
PBF(const vector_tile::Tile &tile);
~PBF();
const QHash<QString, Layer*> &layers() const {return _layers;}
const QHash<QByteArray, Layer*> &layers() const {return _layers;}
private:
QHash<QString, Layer*> _layers;
QHash<QByteArray, Layer*> _layers;
};
inline bool operator<(const PBF::Feature &f1, const PBF::Feature &f2)

View File

@ -26,6 +26,19 @@ static vector_tile::Tile_GeomType geometryType(const QString &str)
return vector_tile::Tile_GeomType_UNKNOWN;
}
static QVariant variant(const QJsonValue &val)
{
switch (val.type()) {
case QJsonValue::String:
return QVariant(val.toString().toUtf8());
case QJsonValue::Double:
case QJsonValue::Bool:
return val.toVariant();
default:
return QVariant();
}
}
Style::Layer::Filter::Filter(const QJsonArray &json)
: _type(Unknown), _not(false)
{
@ -42,43 +55,43 @@ Style::Layer::Filter::Filter(const QJsonArray &json)
INVALID_FILTER(json);
if (json.at(1).toString() == "$type") {
_type = GeometryType;
_kv = QPair<QString, QVariant>(QString(),
_kv = QPair<QByteArray, QVariant>(QByteArray(),
QVariant(geometryType(json.at(2).toString())));
} else {
_type = EQ;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
}
} else if (type == "!=") {
if (json.size() != 3)
INVALID_FILTER(json);
_type = NE;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
} else if (type == "<") {
if (json.size() != 3)
INVALID_FILTER(json);
_type = LT;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
} else if (type == "<=") {
if (json.size() != 3)
INVALID_FILTER(json);
_type = LE;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
} else if (type == ">") {
if (json.size() != 3)
INVALID_FILTER(json);
_type = GT;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
} else if (type == ">=") {
if (json.size() != 3)
INVALID_FILTER(json);
_type = GE;
_kv = QPair<QString, QVariant>(json.at(1).toString(),
json.at(2).toVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
variant(json.at(2)));
} else if (type == "all") {
_type = All;
for (int i = 1; i < json.size(); i++)
@ -91,28 +104,32 @@ Style::Layer::Filter::Filter(const QJsonArray &json)
if (json.size() < 3)
INVALID_FILTER(json);
_type = In;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
for (int i = 2; i < json.size(); i++)
_set.insert(json.at(i).toString());
_set.insert(json.at(i).toString().toUtf8());
} else if (type == "!in") {
if (json.size() < 3)
INVALID_FILTER(json);
_type = In;
_not = true;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
for (int i = 2; i < json.size(); i++)
_set.insert(json.at(i).toString());
_set.insert(json.at(i).toString().toUtf8());
} else if (type == "has") {
if (json.size() < 2)
INVALID_FILTER(json);
_type = Has;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
} else if (type == "!has") {
if (json.size() < 2)
INVALID_FILTER(json);
_type = Has;
_not = true;
_kv = QPair<QString, QVariant>(json.at(1).toString(), QVariant());
_kv = QPair<QByteArray, QVariant>(json.at(1).toString().toUtf8(),
QVariant());
} else
INVALID_FILTER(json);
}
@ -182,7 +199,7 @@ bool Style::Layer::Filter::match(const PBF::Feature &feature) const
if (!(v = feature.value(_kv.first)))
return _not;
else
return _set.contains((*v).toString()) ^ _not;
return _set.contains((*v).toByteArray()) ^ _not;
case Has:
return (feature.value(_kv.first) ? true : false) ^ _not;
case All:
@ -216,7 +233,7 @@ QString Style::Layer::Template::value(int zoom, const PBF::Feature &feature) con
}
for (int i = 0; i < keys.size(); i++) {
const QString &key = keys.at(i);
const QVariant *val = feature.value(key);
const QVariant *val = feature.value(key.toUtf8());
text.replace(QString("{%1}").arg(key), val ? val->toString() : "");
}
@ -486,7 +503,7 @@ Style::Layer::Layer(const QJsonObject &json)
_type = Symbol;
// source-layer
_sourceLayer = json["source-layer"].toString();
_sourceLayer = json["source-layer"].toString().toUtf8();
// zooms
if (json.contains("minzoom") && json["minzoom"].isDouble())
@ -684,7 +701,7 @@ void Style::render(const PBF &data, Tile &tile)
drawBackground(tile);
for (int i = 0; i < _layers.size(); i++) {
QHash<QString, PBF::Layer*>::const_iterator it = data.layers().find(
QHash<QByteArray, PBF::Layer*>::const_iterator it = data.layers().find(
_layers.at(i).sourceLayer());
if (it == data.layers().constEnd())
continue;

View File

@ -37,7 +37,7 @@ private:
Layer() : _type(Unknown), _minZoom(0), _maxZoom(24) {}
Layer(const QJsonObject &json);
const QString &sourceLayer() const {return _sourceLayer;}
const QByteArray &sourceLayer() const {return _sourceLayer;}
bool isPath() const {return (_type == Line || _type == Fill);}
bool isBackground() const {return (_type == Background);}
bool isSymbol() const {return (_type == Symbol);}
@ -74,8 +74,8 @@ private:
Type _type;
bool _not;
QSet<QString> _set;
QPair<QString, QVariant> _kv;
QSet<QByteArray> _set;
QPair<QByteArray, QVariant> _kv;
QVector<Filter> _filters;
};
@ -167,7 +167,7 @@ private:
};
Type _type;
QString _sourceLayer;
QByteArray _sourceLayer;
int _minZoom, _maxZoom;
Filter _filter;
Layout _layout;