我在使用QVector<QPair<QPair<QString, QString>, QString>>实例时遇到了严重的性能问题。
假设我有一个类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
};它在其他类中被引用两次(而不是复制),并直接查询QAbstractListModel子类中的构造:
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 不同的类,还是应该切换到 QMap 或不同类型的容器?
也许在这种情况下也使用Singleton也不是什么好主意?
提前谢谢。
发布于 2022-04-21 19:38:41
通过将表情符号列表解析外包到.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相关的问题,因此我必须为此创建一个额外的问题。
谢谢大家到目前为止的帮助。
https://stackoverflow.com/questions/71956169
复制相似问题