From a91b1a3816397306dda8d35c0ebc741ba69be0a2 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Wed, 24 Jan 2018 13:16:29 +0200 Subject: [PATCH] Speed optimization for method VAbstractPattern::ListMeasurements(). --HG-- branch : develop --- common.pri | 7 +- dist/OBS_debian/debian.control | 2 +- dist/debian/control | 2 +- ...tina-0.0.0_alpha(template_unstable).ebuild | 1 + dist/rpm/valentina.spec | 1 + src/app/tape/tape.pro | 2 +- src/app/valentina/valentina.pro | 3 +- src/libs/ifc/ifc.pro | 2 +- src/libs/ifc/xml/vabstractpattern.cpp | 109 ++++++++---------- src/test/CollectionTest/CollectionTest.pro | 2 +- src/test/ValentinaTest/ValentinaTest.pro | 2 +- 11 files changed, 66 insertions(+), 67 deletions(-) diff --git a/common.pri b/common.pri index 1142b1dc5..664d1ec68 100644 --- a/common.pri +++ b/common.pri @@ -227,7 +227,8 @@ ISYSTEM += \ -isystem "$$[QT_INSTALL_HEADERS]/QtPrintSupport" \ -isystem "$$[QT_INSTALL_HEADERS]/QtSvg" \ -isystem "$$[QT_INSTALL_HEADERS]/QtNetwork" \ - -isystem "$$[QT_INSTALL_HEADERS]/QtTest" + -isystem "$$[QT_INSTALL_HEADERS]/QtTest" \ + -isystem "$$[QT_INSTALL_HEADERS]/QtConcurrent" } else { ISYSTEM += \ -isystem "$$[QT_INSTALL_LIBS]/QtWidgets.framework/Headers/" \ @@ -247,7 +248,9 @@ ISYSTEM += \ -isystem "$$[QT_INSTALL_LIBS]/QtNetwork.framework/Headers/" \ -isystem "$$[QT_INSTALL_LIBS]/QtNetwork.framework/Versions/5/Headers/" \ -isystem "$$[QT_INSTALL_LIBS]/QtTest.framework/Headers/" \ - -isystem "$$[QT_INSTALL_LIBS]/QtTest.framework/Versions/5/Headers/" + -isystem "$$[QT_INSTALL_LIBS]/QtTest.framework/Versions/5/Headers/" \ + -isystem "$$[QT_INSTALL_LIBS]/QtConcurrent.framework/Headers/" \ + -isystem "$$[QT_INSTALL_LIBS]/QtConcurrent.framework/Versions/5/Headers/" } # Usefull GCC warnings keys. diff --git a/dist/OBS_debian/debian.control b/dist/OBS_debian/debian.control index 5e7ea1302..c766e1ba6 100644 --- a/dist/OBS_debian/debian.control +++ b/dist/OBS_debian/debian.control @@ -15,7 +15,7 @@ Vcs-Browser: https://bitbucket.org/dismine/valentina Package: valentina Architecture: i386 amd64 -Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libqt5core5a (>= 5.2.0) | libqt5core5 (>= 5.2.0), libqt5gui5 (>= 5.2.0) | libqt5gui5-gles (>= 5.2.0), libqt5printsupport5 (>= 5.2.0), libqt5svg5 (>= 5.2.0), libqt5widgets5 (>= 5.2.0), libqt5xml5 (>= 5.2.0), libqt5xmlpatterns5 (>= 5.2.0), libstdc++6 (>= 4.6), xpdf +Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libqt5core5a (>= 5.2.0) | libqt5core5 (>= 5.2.0), libqt5gui5 (>= 5.2.0) | libqt5gui5-gles (>= 5.2.0), libqt5printsupport5 (>= 5.2.0), libqt5svg5 (>= 5.2.0), libqt5widgets5 (>= 5.2.0), libqt5xml5 (>= 5.2.0), libqt5xmlpatterns5 (>= 5.2.0), libqt5concurrent5(>= 5.2.0), libstdc++6 (>= 4.6), xpdf Conflicts: seamly2d Description: Pattern making program. Valentina is a cross-platform patternmaking program which allows designers diff --git a/dist/debian/control b/dist/debian/control index 5e7ea1302..c766e1ba6 100644 --- a/dist/debian/control +++ b/dist/debian/control @@ -15,7 +15,7 @@ Vcs-Browser: https://bitbucket.org/dismine/valentina Package: valentina Architecture: i386 amd64 -Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libqt5core5a (>= 5.2.0) | libqt5core5 (>= 5.2.0), libqt5gui5 (>= 5.2.0) | libqt5gui5-gles (>= 5.2.0), libqt5printsupport5 (>= 5.2.0), libqt5svg5 (>= 5.2.0), libqt5widgets5 (>= 5.2.0), libqt5xml5 (>= 5.2.0), libqt5xmlpatterns5 (>= 5.2.0), libstdc++6 (>= 4.6), xpdf +Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libqt5core5a (>= 5.2.0) | libqt5core5 (>= 5.2.0), libqt5gui5 (>= 5.2.0) | libqt5gui5-gles (>= 5.2.0), libqt5printsupport5 (>= 5.2.0), libqt5svg5 (>= 5.2.0), libqt5widgets5 (>= 5.2.0), libqt5xml5 (>= 5.2.0), libqt5xmlpatterns5 (>= 5.2.0), libqt5concurrent5(>= 5.2.0), libstdc++6 (>= 4.6), xpdf Conflicts: seamly2d Description: Pattern making program. Valentina is a cross-platform patternmaking program which allows designers diff --git a/dist/ebuild/valentina-0.0.0_alpha(template_unstable).ebuild b/dist/ebuild/valentina-0.0.0_alpha(template_unstable).ebuild index 0108a0d13..b9c741981 100644 --- a/dist/ebuild/valentina-0.0.0_alpha(template_unstable).ebuild +++ b/dist/ebuild/valentina-0.0.0_alpha(template_unstable).ebuild @@ -34,6 +34,7 @@ CDEPEND=" dev-qt/qtxmlpatterns:5 dev-qt/qtprintsupport:5 dev-qt/qtnetwork:5 + dev-qt/qtconcurrent:5 app-text/poppler" RDEPEND="${CDEPEND}" DEPEND="${CDEPEND} diff --git a/dist/rpm/valentina.spec b/dist/rpm/valentina.spec index 7e6d781e0..82d6ef383 100644 --- a/dist/rpm/valentina.spec +++ b/dist/rpm/valentina.spec @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(Qt5Network) BuildRequires: pkgconfig(Qt5PrintSupport) BuildRequires: pkgconfig(Qt5Widgets) BuildRequires: pkgconfig(Qt5Xml) +BuildRequires: pkgconfig(Qt5Concurrent) BuildRequires: qt5-qtxmlpatterns-devel >= 5.2.0 BuildRequires: qt5-qtsvg-devel >= 5.2.0 BuildRequires: qt5-qttools-devel >= 5.2.0 diff --git a/src/app/tape/tape.pro b/src/app/tape/tape.pro index f7beb7f87..cf271beed 100644 --- a/src/app/tape/tape.pro +++ b/src/app/tape/tape.pro @@ -7,7 +7,7 @@ # File with common stuff for whole project include(../../../common.pri) -QT += core gui widgets network xml xmlpatterns printsupport svg +QT += core gui widgets network xml xmlpatterns printsupport svg concurrent # Name of binary file TARGET = tape diff --git a/src/app/valentina/valentina.pro b/src/app/valentina/valentina.pro index d0fa4db48..0dc1e5422 100644 --- a/src/app/valentina/valentina.pro +++ b/src/app/valentina/valentina.pro @@ -11,7 +11,7 @@ include(../../../common.pri) # Here we don't see "network" library, but, i think, "printsupport" depend on this library, so we still need this # library in installer. -QT += core gui widgets xml svg printsupport xmlpatterns +QT += core gui widgets xml svg printsupport xmlpatterns concurrent # We want create executable file TEMPLATE = app @@ -292,6 +292,7 @@ win32:*g++* { $$[QT_INSTALL_BINS]/icuin*.dll \ # Different name for different Qt releases $$[QT_INSTALL_BINS]/icuuc*.dll \ # Different name for different Qt releases $$[QT_INSTALL_BINS]/Qt5Core.dll \ + $$[QT_INSTALL_BINS]/Qt5Concurrent.dll \ $$[QT_INSTALL_BINS]/Qt5Gui.dll \ $$[QT_INSTALL_BINS]/Qt5Network.dll \ $$[QT_INSTALL_BINS]/Qt5PrintSupport.dll \ diff --git a/src/libs/ifc/ifc.pro b/src/libs/ifc/ifc.pro index 53b34eedd..4d7ceb5b9 100644 --- a/src/libs/ifc/ifc.pro +++ b/src/libs/ifc/ifc.pro @@ -8,7 +8,7 @@ include(../../../common.pri) # Library work with xml. -QT += xml xmlpatterns printsupport +QT += xml xmlpatterns printsupport concurrent # We don't need gui library. QT -= gui diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index 522c481e0..fa1eea53b 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -38,6 +38,9 @@ #include #include #include +#include +#include +#include #include "../exception/vexceptionemptyparameter.h" #include "../exception/vexceptionobjecterror.h" @@ -219,6 +222,19 @@ void ReadExpressionAttribute(QVector &expressions, const QDomElem expressions.append(formula); } + +//--------------------------------------------------------------------------------------------------------------------- +QList GetTokens(const VFormulaField &formula) +{ + QScopedPointer cal(new qmu::QmuTokenParser(formula.expression, false, false)); + return cal->GetTokens().values(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void GatherTokens(QSet &tokens, const QList &tokenList) +{ + tokens = tokens.unite(tokenList.toSet()); +} } //--------------------------------------------------------------------------------------------------------------------- @@ -236,50 +252,22 @@ VAbstractPattern::VAbstractPattern(QObject *parent) //--------------------------------------------------------------------------------------------------------------------- QStringList VAbstractPattern::ListMeasurements() const { + const QFuture futureIncrements = QtConcurrent::run(this, &VAbstractPattern::ListIncrements); + + const QList tokens = QtConcurrent::blockingMappedReduced(ListExpressions(), GetTokens, + GatherTokens).toList(); + QSet measurements; - QSet others; + QSet others = futureIncrements.result().toSet(); - const QStringList increments = ListIncrements(); - for (int i=0; i < increments.size(); ++i) + foreach (const QString &token, tokens) { - others.insert(increments.at(i)); - } - - const QVector expressions = ListExpressions(); - for (int i=0; i < expressions.size(); ++i) - { - // Eval formula - QScopedPointer cal(new qmu::QmuTokenParser(expressions.at(i).expression, false, false)); - const QMap tokens = cal->GetTokens();// Tokens (variables, measurements) - delete cal.take(); - - const QList tValues = tokens.values(); - for (int j = 0; j < tValues.size(); ++j) + if (token == QChar('-') || measurements.contains(token) || others.contains(token)) { - if (tValues.at(j) == QChar('-')) - { - continue; - } - - if (measurements.contains(tValues.at(j))) - { - continue; - } - - if (others.contains(tValues.at(j))) - { - continue; - } - - if (IsVariable(tValues.at(j)) || IsFunction(tValues.at(j))) - { - others.insert(tValues.at(j)); - } - else - { - measurements.insert(tValues.at(j)); - } + continue; } + + IsVariable(token) || IsFunction(token) ? others.insert(token) : measurements.insert(token); } return QStringList(measurements.toList()); @@ -1731,15 +1719,10 @@ QStringList VAbstractPattern::ListIncrements() const const QDomNodeList list = elementsByTagName(type); for (int i=0; i < list.size(); ++i) { - const QDomElement dom = list.at(i).toElement(); - - try + const QString name = GetParametrEmptyString(list.at(i).toElement(), AttrName); + if (not name.isEmpty()) { - increments.append(GetParametrString(dom, AttrName)); - } - catch (VExceptionEmptyParameter &e) - { - Q_UNUSED(e) + increments.append(name); } } }; @@ -1753,20 +1736,30 @@ QStringList VAbstractPattern::ListIncrements() const //--------------------------------------------------------------------------------------------------------------------- QVector VAbstractPattern::ListExpressions() const { - QVector list; - // If new tool bring absolutely new type and has formula(s) create new method to cover it. // Note. Tool Union Details also contains formulas, but we don't use them for union and keep only to simplifying // working with nodes. Same code for saving reading. - list << ListPointExpressions(); - list << ListArcExpressions(); - list << ListElArcExpressions(); - list << ListSplineExpressions(); - list << ListIncrementExpressions(); - list << ListOperationExpressions(); - list << ListPathExpressions(); - list << ListPieceExpressions(); - list << ListFinalMeasurementsExpressions(); + auto futurePointExpressions = QtConcurrent::run(this, &VAbstractPattern::ListPointExpressions); + auto futureArcExpressions = QtConcurrent::run(this, &VAbstractPattern::ListArcExpressions); + auto futureElArcExpressions = QtConcurrent::run(this, &VAbstractPattern::ListElArcExpressions); + auto futureSplineExpressions = QtConcurrent::run(this, &VAbstractPattern::ListSplineExpressions); + auto futureIncrementExpressions = QtConcurrent::run(this, &VAbstractPattern::ListIncrementExpressions); + auto futureOperationExpressions = QtConcurrent::run(this, &VAbstractPattern::ListOperationExpressions); + auto futurePathExpressions = QtConcurrent::run(this, &VAbstractPattern::ListPathExpressions); + auto futurePieceExpressions = QtConcurrent::run(this, &VAbstractPattern::ListPieceExpressions); + auto futureFinalMeasurementsExpressions = QtConcurrent::run(this, + &VAbstractPattern::ListFinalMeasurementsExpressions); + + QVector list; + list << futurePointExpressions.result(); + list << futureArcExpressions.result(); + list << futureElArcExpressions.result(); + list << futureSplineExpressions.result(); + list << futureIncrementExpressions.result(); + list << futureOperationExpressions.result(); + list << futurePathExpressions.result(); + list << futurePieceExpressions.result(); + list << futureFinalMeasurementsExpressions.result(); return list; } diff --git a/src/test/CollectionTest/CollectionTest.pro b/src/test/CollectionTest/CollectionTest.pro index ea09240b0..b87a42220 100644 --- a/src/test/CollectionTest/CollectionTest.pro +++ b/src/test/CollectionTest/CollectionTest.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += testlib widgets printsupport +QT += testlib widgets printsupport concurrent QT -= gui diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index 69d2fd1ea..7ed39e52c 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core testlib gui printsupport xml xmlpatterns +QT += core testlib gui printsupport xml xmlpatterns concurrent TARGET = ValentinaTests