Testlib: Replace linked lists in QTestTablePrivate by std::vector.
This speeds up tests/auto/corelib/tools/qchar which spends a lot of time in QTestTablePrivate::elementAt(), QTestTablePrivate::dataAt() from 6s to 500ms on an average Linux machine. Task-number: QTBUG-38890 Change-Id: I16b75819f88ca7974a581affd8409f7b4038a712 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>bb10
parent
9f66b1dd71
commit
7a42c8c15c
|
|
@ -38,37 +38,30 @@
|
|||
#include <QtCore/qmetaobject.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTestTablePrivate
|
||||
{
|
||||
public:
|
||||
struct ElementList
|
||||
{
|
||||
ElementList(): elementName(0), elementType(0), next(0) {}
|
||||
const char *elementName;
|
||||
int elementType;
|
||||
ElementList *next;
|
||||
struct Element {
|
||||
Element() : name(Q_NULLPTR), type(0) {}
|
||||
Element(const char *n, int t) : name(n), type(t) {}
|
||||
|
||||
const char *name;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct DataList
|
||||
{
|
||||
DataList(): data(0), next(0) {}
|
||||
QTestData *data;
|
||||
DataList *next;
|
||||
};
|
||||
typedef std::vector<Element> ElementList;
|
||||
ElementList elementList;
|
||||
|
||||
QTestTablePrivate(): list(0), dataList(0) {}
|
||||
~QTestTablePrivate();
|
||||
typedef std::vector<QTestData *> DataList;
|
||||
DataList dataList;
|
||||
|
||||
ElementList *list;
|
||||
DataList *dataList;
|
||||
|
||||
void addColumn(int elemType, const char *elemName);
|
||||
void addRow(QTestData *data);
|
||||
ElementList *elementAt(int index);
|
||||
QTestData *dataAt(int index);
|
||||
void addColumn(int elemType, const char *elemName) { elementList.push_back(Element(elemName, elemType)); }
|
||||
void addRow(QTestData *data) { dataList.push_back(data); }
|
||||
|
||||
static QTestTable *currentTestTable;
|
||||
static QTestTable *gTable;
|
||||
|
|
@ -77,74 +70,6 @@ public:
|
|||
QTestTable *QTestTablePrivate::currentTestTable = 0;
|
||||
QTestTable *QTestTablePrivate::gTable = 0;
|
||||
|
||||
QTestTablePrivate::ElementList *QTestTablePrivate::elementAt(int index)
|
||||
{
|
||||
ElementList *iter = list;
|
||||
for (int i = 0; i < index; ++i) {
|
||||
if (!iter)
|
||||
return 0;
|
||||
iter = iter->next;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
QTestData *QTestTablePrivate::dataAt(int index)
|
||||
{
|
||||
DataList *iter = dataList;
|
||||
for (int i = 0; i < index; ++i) {
|
||||
if (!iter)
|
||||
return 0;
|
||||
iter = iter->next;
|
||||
}
|
||||
return iter ? iter->data : 0;
|
||||
}
|
||||
|
||||
QTestTablePrivate::~QTestTablePrivate()
|
||||
{
|
||||
DataList *dit = dataList;
|
||||
while (dit) {
|
||||
DataList *next = dit->next;
|
||||
delete dit->data;
|
||||
delete dit;
|
||||
dit = next;
|
||||
}
|
||||
ElementList *iter = list;
|
||||
while (iter) {
|
||||
ElementList *next = iter->next;
|
||||
delete iter;
|
||||
iter = next;
|
||||
}
|
||||
}
|
||||
|
||||
void QTestTablePrivate::addColumn(int elemType, const char *elemName)
|
||||
{
|
||||
ElementList *item = new ElementList;
|
||||
item->elementName = elemName;
|
||||
item->elementType = elemType;
|
||||
if (!list) {
|
||||
list = item;
|
||||
return;
|
||||
}
|
||||
ElementList *last = list;
|
||||
while (last->next != 0)
|
||||
last = last->next;
|
||||
last->next = item;
|
||||
}
|
||||
|
||||
void QTestTablePrivate::addRow(QTestData *data)
|
||||
{
|
||||
DataList *item = new DataList;
|
||||
item->data = data;
|
||||
if (!dataList) {
|
||||
dataList = item;
|
||||
return;
|
||||
}
|
||||
DataList *last = dataList;
|
||||
while (last->next != 0)
|
||||
last = last->next;
|
||||
last->next = item;
|
||||
}
|
||||
|
||||
void QTestTable::addColumn(int type, const char *name)
|
||||
{
|
||||
QTEST_ASSERT(type);
|
||||
|
|
@ -155,30 +80,17 @@ void QTestTable::addColumn(int type, const char *name)
|
|||
|
||||
int QTestTable::elementCount() const
|
||||
{
|
||||
QTestTablePrivate::ElementList *item = d->list;
|
||||
int count = 0;
|
||||
while (item) {
|
||||
++count;
|
||||
item = item->next;
|
||||
}
|
||||
return count;
|
||||
return int(d->elementList.size());
|
||||
}
|
||||
|
||||
|
||||
int QTestTable::dataCount() const
|
||||
{
|
||||
QTestTablePrivate::DataList *item = d->dataList;
|
||||
int count = 0;
|
||||
while (item) {
|
||||
++count;
|
||||
item = item->next;
|
||||
}
|
||||
return count;
|
||||
return int(d->dataList.size());
|
||||
}
|
||||
|
||||
bool QTestTable::isEmpty() const
|
||||
{
|
||||
return !d->list;
|
||||
return d->elementList.empty();
|
||||
}
|
||||
|
||||
QTestData *QTestTable::newData(const char *tag)
|
||||
|
|
@ -202,38 +114,43 @@ QTestTable::~QTestTable()
|
|||
|
||||
int QTestTable::elementTypeId(int index) const
|
||||
{
|
||||
QTestTablePrivate::ElementList *item = d->elementAt(index);
|
||||
if (!item)
|
||||
return -1;
|
||||
return item->elementType;
|
||||
return size_t(index) < d->elementList.size() ? d->elementList[index].type : -1;
|
||||
}
|
||||
|
||||
const char *QTestTable::dataTag(int index) const
|
||||
{
|
||||
QTestTablePrivate::ElementList *item = d->elementAt(index);
|
||||
if (!item)
|
||||
return 0;
|
||||
return item->elementName;
|
||||
return size_t(index) < d->elementList.size() ? d->elementList[index].name : Q_NULLPTR;
|
||||
}
|
||||
|
||||
QTestData *QTestTable::testData(int index) const
|
||||
{
|
||||
return d->dataAt(index);
|
||||
return size_t(index) < d->dataList.size() ? d->dataList[index] : Q_NULLPTR;
|
||||
}
|
||||
|
||||
class NamePredicate : public std::unary_function<QTestTablePrivate::Element, bool>
|
||||
{
|
||||
public:
|
||||
explicit NamePredicate(const char *needle) : m_needle(needle) {}
|
||||
|
||||
bool operator()(const QTestTablePrivate::Element &e) const
|
||||
{ return !strcmp(e.name, m_needle); }
|
||||
|
||||
private:
|
||||
const char *m_needle;
|
||||
};
|
||||
|
||||
int QTestTable::indexOf(const char *elementName) const
|
||||
{
|
||||
typedef QTestTablePrivate::ElementList::const_iterator It;
|
||||
|
||||
QTEST_ASSERT(elementName);
|
||||
|
||||
QTestTablePrivate::ElementList *item = d->list;
|
||||
int i = 0;
|
||||
while (item) {
|
||||
if (strcmp(elementName, item->elementName) == 0)
|
||||
return i;
|
||||
item = item->next;
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
const QTestTablePrivate::ElementList &elementList = d->elementList;
|
||||
|
||||
const It it = std::find_if(elementList.begin(), elementList.end(),
|
||||
NamePredicate(elementName));
|
||||
return it != elementList.end() ?
|
||||
int(it - elementList.begin()) : -1;
|
||||
}
|
||||
|
||||
QTestTable *QTestTable::globalTestTable()
|
||||
|
|
|
|||
Loading…
Reference in New Issue