使用QVector<QPair<QPair<QString, QString>、QString的性能问题>>
Performance problems using QVector<QPair<QPair<QString, QString>, QString>>
我在使用 QVector<QPair<QPair<QString, QString>, QString>>
实例时遇到严重的性能问题。
假设我有一个 class EmojiList
,它除了保存这个填充了大约 4000 个表情符号及其各自的简称和类别的向量之外什么都不做:
emojilist.h
#include <QVector>
class EmojiList {
public:
static const QVector<QPair<QPair<QString, QString>, QString>>& list() {
static EmojiList list;
return list.emojiList;
}
private:
QVector<QPair<QPair<QString, QString>, QString>> emojiList {
{ { "", ":woman_woman_girl_girl:" }, "People & Body" },
{ { "", ":woman_woman_girl_boy:" }, "People & Body" },
{ { "", ":woman_woman_boy_boy:" }, "People & Body" },
{ { "", ":man_woman_girl_girl:" }, "People & Body" },
{ { "", ":man_woman_girl_boy:" }, "People & Body" },
// ... ~ 4000 entries to come
};
它在其他 class 中被引用(未 复制)两次,并在 QAbstractListModel
子class 中直接在构造时查询:
emojilistmodel.h
#include "emojilist.h"
class EmojiListModel : public QAbstractTableModel
{
Q_OBJECT
// ...
private:
const QVector<QPair<QPair<QString, QString>, QString>>& _emojiMap { EmojiList::list() };
当编译我的应用程序时,包括 emojilist.h
,编译大约需要 1:20 分钟,没有 emojilist.h
,需要 3.8 秒。
此外,启动应用程序比不包含 emojilist.h
时花费的时间长得多:不包含 emojilist.h
的启动时间为 4 秒,包含 emojilist.h
的启动时间为 3:40分钟.
如何优化我的代码以提高性能和速度?我应该使用不同于 QVector
的 class 还是应该切换到 QMap
或不同类型的容器?
也许在这种情况下也使用 Singleton 并不是一个好主意?
非常感谢。
我通过将表情符号列表解析外包到 .cpp
文件中,设法将编译时间减少到 3 秒:
emojilist.h
#include <QVector>
class EmojiList {
public:
struct EmojiData {
EmojiData(const QString& _code, const QString& _shortname, const QString& _category) :
code(_code),
shortname(_shortname),
category(_category)
{}
QString code;
QString shortname;
QString category;
};
static const QVector<EmojiData>& list();
private:
QVector<EmojiData> emojiList;
void parseFromFile();
};
emojilist.cpp
#include "emojilist.h"
#include <QFile>
#include <QTextStream>
const QVector<EmojiList::EmojiData>& EmojiList::list()
{
static EmojiList list;
if (list.emojiList.isEmpty()) {
list.parseFromFile();
}
return list.emojiList;
}
void EmojiList::parseFromFile()
{
QFile emojiResource { ":/media/new_emoji.list" };
if (emojiResource.open(QIODevice::ReadOnly)) {
QTextStream in { &emojiResource };
while (!in.atEnd()) {
QStringList line { in.readLine().split(',') };
emojiList.append({ line.at(0), line.at(1), line.at(2) });
}
}
emojiResource.close();
}
然后在我的列表模型中检索它:
emojilistmodel.cpp
QVariant EmojiListModel::data(const QModelIndex &index, int role) const
{
if (_emojiMap.isEmpty() || !index.isValid() || index.row() > _emojiMap.size()) {
return QVariant();
}
switch (role) {
case EmojiName:
return _emojiMap.at(index.row()).shortname;
case Emoji:
return _emojiMap.at(index.row()).code;
case EmojiCategory: {
return _emojiMap.at(index.row()).category;
}
default:
return QVariant();
}
}
它工作得很好,但是启动仍然需要很长时间(5 分钟以上)。无论如何,这似乎是一个 QML-related 问题 所以我必须为此创建一个额外的问题。
非常感谢大家到目前为止的帮助。
我在使用 QVector<QPair<QPair<QString, QString>, QString>>
实例时遇到严重的性能问题。
假设我有一个 class EmojiList
,它除了保存这个填充了大约 4000 个表情符号及其各自的简称和类别的向量之外什么都不做:
emojilist.h
#include <QVector>
class EmojiList {
public:
static const QVector<QPair<QPair<QString, QString>, QString>>& list() {
static EmojiList list;
return list.emojiList;
}
private:
QVector<QPair<QPair<QString, QString>, QString>> emojiList {
{ { "", ":woman_woman_girl_girl:" }, "People & Body" },
{ { "", ":woman_woman_girl_boy:" }, "People & Body" },
{ { "", ":woman_woman_boy_boy:" }, "People & Body" },
{ { "", ":man_woman_girl_girl:" }, "People & Body" },
{ { "", ":man_woman_girl_boy:" }, "People & Body" },
// ... ~ 4000 entries to come
};
它在其他 class 中被引用(未 复制)两次,并在 QAbstractListModel
子class 中直接在构造时查询:
emojilistmodel.h
#include "emojilist.h"
class EmojiListModel : public QAbstractTableModel
{
Q_OBJECT
// ...
private:
const QVector<QPair<QPair<QString, QString>, QString>>& _emojiMap { EmojiList::list() };
当编译我的应用程序时,包括 emojilist.h
,编译大约需要 1:20 分钟,没有 emojilist.h
,需要 3.8 秒。
此外,启动应用程序比不包含 emojilist.h
时花费的时间长得多:不包含 emojilist.h
的启动时间为 4 秒,包含 emojilist.h
的启动时间为 3:40分钟.
如何优化我的代码以提高性能和速度?我应该使用不同于 QVector
的 class 还是应该切换到 QMap
或不同类型的容器?
也许在这种情况下也使用 Singleton 并不是一个好主意?
非常感谢。
我通过将表情符号列表解析外包到 .cpp
文件中,设法将编译时间减少到 3 秒:
emojilist.h
#include <QVector>
class EmojiList {
public:
struct EmojiData {
EmojiData(const QString& _code, const QString& _shortname, const QString& _category) :
code(_code),
shortname(_shortname),
category(_category)
{}
QString code;
QString shortname;
QString category;
};
static const QVector<EmojiData>& list();
private:
QVector<EmojiData> emojiList;
void parseFromFile();
};
emojilist.cpp
#include "emojilist.h"
#include <QFile>
#include <QTextStream>
const QVector<EmojiList::EmojiData>& EmojiList::list()
{
static EmojiList list;
if (list.emojiList.isEmpty()) {
list.parseFromFile();
}
return list.emojiList;
}
void EmojiList::parseFromFile()
{
QFile emojiResource { ":/media/new_emoji.list" };
if (emojiResource.open(QIODevice::ReadOnly)) {
QTextStream in { &emojiResource };
while (!in.atEnd()) {
QStringList line { in.readLine().split(',') };
emojiList.append({ line.at(0), line.at(1), line.at(2) });
}
}
emojiResource.close();
}
然后在我的列表模型中检索它:
emojilistmodel.cpp
QVariant EmojiListModel::data(const QModelIndex &index, int role) const
{
if (_emojiMap.isEmpty() || !index.isValid() || index.row() > _emojiMap.size()) {
return QVariant();
}
switch (role) {
case EmojiName:
return _emojiMap.at(index.row()).shortname;
case Emoji:
return _emojiMap.at(index.row()).code;
case EmojiCategory: {
return _emojiMap.at(index.row()).category;
}
default:
return QVariant();
}
}
它工作得很好,但是启动仍然需要很长时间(5 分钟以上)。无论如何,这似乎是一个 QML-related 问题 所以我必须为此创建一个额外的问题。
非常感谢大家到目前为止的帮助。