如何优化大 QStringList 的代码?
How can I optimize the code for big QStringList?
如果 list2 包含超过 200,000 个条目,则以下代码似乎无法在可容忍的时间内完成。
QStringList list1;
QStringList list2=getalist();
int count=list2.count();
for(int j=0;j<count;j++)
{
QString e=list2[j];
if(!list1.contains(e,Qt::CaseInsensitive))
{
list1<<e;
}
}
瓶颈是什么,如何优化?
瓶颈在于选择 QStringList
作为该任务的容器。它是一个 QList<QString>
,我相信它使用线性搜索来实现函数 contains
。
最好的解决方案是使用像 std::set 这样的 tree-based 容器或像 QSet
这样基于散列的容器(是的,它基于散列与 std::set).来自 Qt documentation:
QSet is one of Qt's generic container classes. It stores values in
an unspecified order and provides very fast lookup of the values.
Internally, QSet is implemented as a QHash.
您的代码似乎将 list1
更新为 list1
和 list2
中所有唯一元素的并集,比较时不区分大小写。所以像(未经测试)...
QStringList list1;
QStringList list2 = getalist();
struct case_insensitive_compare {
bool operator() (const QString &l, const QString &r) const
{
return l.compare(r, Qt::CaseInsensitive) < 0;
}
};
std::set<QString, case_insensitive_compare> set1(list1.begin(), list1.end());
set1.insert(list2.begin(), list2.end());
list1 = QStringList(set1.begin(), set1.end());
如果 list2 包含超过 200,000 个条目,则以下代码似乎无法在可容忍的时间内完成。
QStringList list1;
QStringList list2=getalist();
int count=list2.count();
for(int j=0;j<count;j++)
{
QString e=list2[j];
if(!list1.contains(e,Qt::CaseInsensitive))
{
list1<<e;
}
}
瓶颈是什么,如何优化?
瓶颈在于选择 QStringList
作为该任务的容器。它是一个 QList<QString>
,我相信它使用线性搜索来实现函数 contains
。
最好的解决方案是使用像 std::set 这样的 tree-based 容器或像 QSet
这样基于散列的容器(是的,它基于散列与 std::set).来自 Qt documentation:
QSet is one of Qt's generic container classes. It stores values in an unspecified order and provides very fast lookup of the values. Internally, QSet is implemented as a QHash.
您的代码似乎将 list1
更新为 list1
和 list2
中所有唯一元素的并集,比较时不区分大小写。所以像(未经测试)...
QStringList list1;
QStringList list2 = getalist();
struct case_insensitive_compare {
bool operator() (const QString &l, const QString &r) const
{
return l.compare(r, Qt::CaseInsensitive) < 0;
}
};
std::set<QString, case_insensitive_compare> set1(list1.begin(), list1.end());
set1.insert(list2.begin(), list2.end());
list1 = QStringList(set1.begin(), set1.end());