diff --git a/samples/blackmisc/main.cpp b/samples/blackmisc/main.cpp index ab995acf5..94d9dfd49 100644 --- a/samples/blackmisc/main.cpp +++ b/samples/blackmisc/main.cpp @@ -13,6 +13,7 @@ #include "samplescontainer.h" #include "samplesjson.h" #include "samplesvariant.h" +#include "samplesperformance.h" #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/pqallquantities.h" @@ -30,10 +31,28 @@ int main(int argc, char *argv[]) BlackMisc::initResources(); BlackMisc::registerMetadata(); - CSamplesJson::samples(); - CSamplesChangeObject::samples(); - CSamplesContainer::samples(); - CSamplesMetadata::samples(); - CSamplesVariant::samples(); + + do + { + qDebug() << "1 .. JSON"; + qDebug() << "2 .. Change object"; + qDebug() << "3 .. Containers"; + qDebug() << "4 .. Metadata"; + qDebug() << "5 .. Variant"; + qDebug() << "6 .. Performance"; + qDebug() << "-----"; + qDebug() << "x .. Bye"; + QTextStream qtin(stdin); + QString s = qtin.readLine().toLower().trimmed(); + + if (s.startsWith("1")) { CSamplesJson::samples(); } + else if (s.startsWith("2")) { CSamplesChangeObject::samples(); } + else if (s.startsWith("3")) { CSamplesContainer::samples(); } + else if (s.startsWith("4")) { CSamplesMetadata::samples(); } + else if (s.startsWith("5")) { CSamplesVariant::samples(); } + else if (s.startsWith("6")) { CSamplesPerformance::samples(); } + else if (s.startsWith("x")) { break; } + } + while (true); return 0; } diff --git a/samples/blackmisc/samplesperformance.cpp b/samples/blackmisc/samplesperformance.cpp new file mode 100644 index 000000000..74f05b87e --- /dev/null +++ b/samples/blackmisc/samplesperformance.cpp @@ -0,0 +1,118 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "samplesperformance.h" +#include "blackmisc/testing.h" + +using namespace BlackMisc::Aviation; + +namespace BlackMiscTest +{ + + /* + * Samples + */ + int CSamplesPerformance::samples() + { + QTime timer; + int ms, number; + BlackMisc::Aviation::CTesting::copy10kStations(1); // init + + // ATC stations, tradionally created + timer.start(); + CAtcStationList atcs1 = BlackMisc::Aviation::CTesting::createAtcStations(10000); + ms = timer.elapsed(); + qDebug() << "created (copy)" << atcs1.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + CAtcStationList atcs2 = BlackMisc::Aviation::CTesting::createAtcStations(100000); + ms = timer.elapsed(); + qDebug() << "created (copy)" << atcs2.size() << "ATC stations in" << ms << "ms"; + + // ATC stations, property index created + timer.start(); + CAtcStationList atcs3 = BlackMisc::Aviation::CTesting::createAtcStations(10000, true); + ms = timer.elapsed(); + qDebug() << "created (propertyIndex)" << atcs3.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + CAtcStationList atcs4 = BlackMisc::Aviation::CTesting::createAtcStations(100000, true); + ms = timer.elapsed(); + qDebug() << "created (propertyIndex)" << atcs4.size() << "ATC stations in" << ms << "ms"; + + // Sort by + timer.start(); + atcs1.sortBy(&CAtcStation::getCallsign); + ms = timer.elapsed(); + qDebug() << "Sorted by callsign" << atcs1.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + atcs2.sortBy(&CAtcStation::getCallsign); + ms = timer.elapsed(); + qDebug() << "Sorted by callsign" << atcs2.size() << "ATC stations in" << ms << "ms"; + + // Read data, this is what all our models do when displaying in a table view + timer.start(); + BlackMisc::Aviation::CTesting::readStations(atcs1, false); + ms = timer.elapsed(); + qDebug() << "Read (getters)" << atcs1.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + BlackMisc::Aviation::CTesting::readStations(atcs2, false); + ms = timer.elapsed(); + qDebug() << "Read (getters)" << atcs2.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + BlackMisc::Aviation::CTesting::readStations(atcs1, true); + ms = timer.elapsed(); + qDebug() << "Read (propertyIndex)" << atcs1.size() << "ATC stations in" << ms << "ms"; + + timer.start(); + BlackMisc::Aviation::CTesting::readStations(atcs2, true); + ms = timer.elapsed(); + qDebug() << "Read (propertyIndex)" << atcs2.size() << "ATC stations in" << ms << "ms"; + + // calculate + number = 10000; + timer.start(); + BlackMisc::Aviation::CTesting::calculateDistance(number); + ms = timer.elapsed(); + qDebug() << "Calculated distances " << number << "in" << ms << "ms"; + + number = 100000; + timer.start(); + BlackMisc::Aviation::CTesting::calculateDistance(number); + ms = timer.elapsed(); + qDebug() << "Calculated distances " << number << "in" << ms << "ms"; + + // parse + number = 100000; + timer.start(); + BlackMisc::Aviation::CTesting::parseWgs(number); + ms = timer.elapsed(); + qDebug() << "Parse WGS coordinates" << number << "in" << ms << "ms"; + + // copy + timer.start(); + number = 20; + BlackMisc::Aviation::CTesting::copy10kStations(number); + ms = timer.elapsed(); + qDebug() << "Copied 10k stations" << number << "times in" << ms << "ms"; + + timer.start(); + number = 100; + BlackMisc::Aviation::CTesting::copy10kStations(number); + ms = timer.elapsed(); + qDebug() << "Copied 10k stations" << number << "times in" << ms << "ms"; + + qDebug() << "-----------------------------------------------"; + return 0; + } + +} // namespace diff --git a/samples/blackmisc/samplesperformance.h b/samples/blackmisc/samplesperformance.h new file mode 100644 index 000000000..d0746a7e8 --- /dev/null +++ b/samples/blackmisc/samplesperformance.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2013 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISCTEST_SAMPLESPERFORMANCEINDEX_H +#define BLACKMISCTEST_SAMPLESPERFORMANCEINDEX_H + +namespace BlackMiscTest +{ + //! Samples for our containers + class CSamplesPerformance + { + public: + //! Run the samples + static int samples(); + }; +} // namespace + +#endif diff --git a/src/blackmisc/geoearthangle.cpp b/src/blackmisc/geoearthangle.cpp index 625189d0b..845c53c1f 100644 --- a/src/blackmisc/geoearthangle.cpp +++ b/src/blackmisc/geoearthangle.cpp @@ -32,6 +32,7 @@ namespace BlackMisc template LATorLON CEarthAngle::fromWgs84(const QString &wgsCoordinate) { // http://www.regular-expressions.info/floatingpoint.html + const QString wgs = wgsCoordinate.simplified().trimmed(); QRegExp rx("([-+]?[0-9]*\\.?[0-9]+)"); qint32 deg = 0; qint32 min = 0; @@ -40,7 +41,7 @@ namespace BlackMisc int fragmentLength = 0; int c = 0; int pos = 0; - while ((pos = rx.indexIn(wgsCoordinate, pos)) != -1) + while ((pos = rx.indexIn(wgs, pos)) != -1) { QString cap = rx.cap(1); pos += rx.matchedLength(); @@ -65,12 +66,12 @@ namespace BlackMisc } if (fragmentLength > 0) { - // we do have given ms + // we do have given ms in string sec += secFragment / qPow(10, fragmentLength); } - if (wgsCoordinate.contains('S', Qt::CaseInsensitive) || - wgsCoordinate.contains('W', Qt::CaseInsensitive)) deg *= -1; + if (wgs.contains('S', Qt::CaseInsensitive) || + wgs.contains('W', Qt::CaseInsensitive)) deg *= -1; CAngle a(deg, min, sec); return LATorLON(a); diff --git a/src/blackmisc/testing.cpp b/src/blackmisc/testing.cpp index 89d4060ec..4a69a78bd 100644 --- a/src/blackmisc/testing.cpp +++ b/src/blackmisc/testing.cpp @@ -31,7 +31,10 @@ namespace BlackMisc CAtcStation CTesting::createStation(int index, bool byPropertyIndex) { - // ATC station + // from WGS is slow, so static const (only 1 time init) + // https://dev.vatsim-germany.org/issues/322#note-2 + static const CCoordinateGeodetic geoPos = CCoordinateGeodetic::fromWgs84("48° 21′ 13″ N", "11° 47′ 09″ E", CLength(index, CLengthUnit::ft())); + QString cs = QString("%1_TWR").arg(index); QString usr = QString("Joe %1").arg(index); QString id = QString("00000%1").arg(index).right(6); @@ -39,11 +42,9 @@ namespace BlackMisc QDateTime dtFrom = QDateTime::currentDateTimeUtc(); QDateTime dtUntil = dtFrom.addSecs(60 * 60.0); // 1 hour - CCoordinateGeodetic geoPos = CCoordinateGeodetic::fromWgs84("48° 21′ 13″ N", "11° 47′ 09″ E", CLength(index, CLengthUnit::ft())); if (byPropertyIndex) { - CAtcStation station; station.setPropertyByIndex(CCallsign(cs).toQVariant(), CAtcStation::IndexCallsign); station.setPropertyByIndex(CUser(id, usr).toQVariant(), CAtcStation::IndexController); @@ -125,15 +126,34 @@ namespace BlackMisc void CTesting::copy10kStations(int times) { - int s = 0; CAtcStationList stations; for (int i = 0; i < times; i++) { stations = stations10k(); - s += stations.size(); // make sure stations is used + stations.pop_back(); // make sure stations are really copied (copy-on-write) + } + } + + + void CTesting::parseWgs(int times) + { + static QStringList wgsLatLng( + { + "12° 11′ 10″ N", "11° 22′ 33″ W", + "48° 21′ 13″ N", "11° 47′ 09″ E", + " 8° 21′ 13″ N", "11° 47′ 09″ W", + "18° 21′ 13″ S", "11° 47′ 09″ E", + "09° 12′ 13″ S", "11° 47′ 09″ W" + } + ); + + CCoordinateGeodetic c; + const CLength h(333, CLengthUnit::m()); + for (int i = 0; i < times; i++) + { + int idx = (i % 5) * 2; + c = CCoordinateGeodetic::fromWgs84(wgsLatLng.at(idx), wgsLatLng.at(idx + 1), h); } - Q_ASSERT(s == times * 10000); - Q_UNUSED(s); } } // namespace diff --git a/src/blackmisc/testing.h b/src/blackmisc/testing.h index d46e7f934..ce959e505 100644 --- a/src/blackmisc/testing.h +++ b/src/blackmisc/testing.h @@ -51,6 +51,8 @@ namespace BlackMisc return s; } + //! parse coordinates from WGS + static void parseWgs(int times); }; } // Aviation