Browse Source

New performance testing tools

Added src/testing dir with  ATimer (execution timer) and ABenchmark (compare functions) for performance testing purposes.
Felix Turo 4 years ago
parent
commit
a378101516

+ 1 - 1
mainwindow.cpp

@@ -17,7 +17,7 @@
  */
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)

+ 7 - 4
openPilotLog.pro

@@ -47,7 +47,9 @@ SOURCES += \
     src/gui/widgets/logbookwidget.cpp \
     src/gui/widgets/pilotswidget.cpp \
     src/gui/widgets/settingswidget.cpp \
-    src/gui/widgets/totalswidget.cpp
+    src/gui/widgets/totalswidget.cpp \
+    src/testing/abenchmark.cpp \
+    src/testing/atimer.cpp
 
 HEADERS += \
     mainwindow.h \
@@ -70,8 +72,6 @@ HEADERS += \
     src/experimental/atailentry.h \
     src/experimental/decl.h \
     src/functions/acalc.h \
-    src/functions/adebug.h \
-    src/functions/src/functions/adebug.h \
     src/functions/areadcsv.h \
     src/functions/astat.h \
     src/gui/dialogues/firstrundialog.h \
@@ -84,7 +84,10 @@ HEADERS += \
     src/gui/widgets/logbookwidget.h \
     src/gui/widgets/pilotswidget.h \
     src/gui/widgets/settingswidget.h \
-    src/gui/widgets/totalswidget.h
+    src/gui/widgets/totalswidget.h \
+    src/testing/abenchmark.h \
+    src/testing/adebug.h \
+    src/testing/atimer.h
 
 FORMS += \
     mainwindow.ui \

+ 1 - 1
src/classes/adownload.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "adownload.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 

+ 1 - 1
src/classes/aircraft.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "aircraft.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 Aircraft::Aircraft()

+ 1 - 1
src/classes/flight.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "flight.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 Flight::Flight()
 {

+ 1 - 1
src/classes/pilot.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "pilot.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 

+ 1 - 1
src/database/adatabasesetup.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "adatabasesetup.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 // Statements for creation of database tables, Revision 12

+ 1 - 1
src/database/db.cpp

@@ -17,7 +17,7 @@
  */
 #include "db.h"
 #include "dbinfo.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 /*!
  * \brief Db::iconnect - see Db::connect

+ 1 - 1
src/database/dbinfo.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "dbinfo.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 DbInfo::DbInfo()
 {

+ 1 - 1
src/database/entry_deprecated.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "entry_deprecated.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 #include "db.h"
 
 Entry_deprecated::Entry_deprecated()

+ 0 - 8
src/experimental/ADebug.h

@@ -1,8 +0,0 @@
-#ifndef ADEBUG_H
-#define ADEBUG_H
-
-#include <QDebug>
-
-#define DEB qDebug()
-
-#endif

+ 1 - 1
src/experimental/adatabase.h

@@ -25,7 +25,7 @@
 #include <QSqlError>
 #include <QSqlTableModel>
 #include "src/database/dbinfo.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 #include "aentry.h"
 #include "apilotentry.h"

+ 1 - 1
src/functions/acalc.cpp

@@ -1,5 +1,5 @@
 #include "acalc.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 using namespace ACalc;
 

+ 1 - 1
src/functions/astat.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "astat.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 using namespace experimental;
 

+ 1 - 1
src/gui/dialogues/newflightdialog.cpp

@@ -17,7 +17,7 @@
  */
 #include "newflightdialog.h"
 #include "ui_newflight.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 

+ 1 - 1
src/gui/dialogues/newpilotdialog.cpp

@@ -17,7 +17,7 @@
  */
 #include "newpilotdialog.h"
 #include "ui_newpilot.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 /* Examples for names around the world:
  * José Eduardo Santos Tavares Melo Silva

+ 1 - 1
src/gui/dialogues/newtaildialog.cpp

@@ -17,7 +17,7 @@
  */
 #include "newtaildialog.h"
 #include "ui_newtail.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 static const auto REG_VALID = QPair<QString, QRegularExpression> {
     "registrationLineEdit", QRegularExpression("\\w+-\\w+")};

+ 6 - 1
src/gui/widgets/debugwidget.cpp

@@ -1,6 +1,6 @@
 #include "debugwidget.h"
 #include "ui_debugwidget.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 DebugWidget::DebugWidget(QWidget *parent) :
@@ -158,3 +158,8 @@ void DebugWidget::on_importCsvPushButton_clicked()
         mb.exec();
     }
 }
+
+void DebugWidget::on_debugPushButton_clicked()
+{
+
+}

+ 2 - 0
src/gui/widgets/debugwidget.h

@@ -39,6 +39,8 @@ private slots:
 
     void on_importCsvPushButton_clicked();
 
+    void on_debugPushButton_clicked();
+
 private:
     Ui::DebugWidget *ui;
 

+ 54 - 44
src/gui/widgets/debugwidget.ui

@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>640</width>
+    <width>1005</width>
     <height>480</height>
    </rect>
   </property>
@@ -24,44 +24,49 @@
        <string>Database</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_2">
-       <item row="0" column="0">
-        <widget class="QPushButton" name="resetDatabasePushButton">
+       <item row="3" column="3">
+        <widget class="QLineEdit" name="importCsvLineEdit">
          <property name="minimumSize">
           <size>
-           <width>220</width>
+           <width>110</width>
            <height>0</height>
           </size>
          </property>
-         <property name="text">
-          <string>Reset Database</string>
+         <property name="placeholderText">
+          <string>/path/to/file.csv</string>
          </property>
         </widget>
        </item>
-       <item row="3" column="1" colspan="2">
-        <widget class="QComboBox" name="tableComboBox">
+       <item row="3" column="4">
+        <widget class="QPushButton" name="selectCsvPushButton">
          <property name="minimumSize">
           <size>
            <width>110</width>
            <height>0</height>
           </size>
          </property>
-         <item>
-          <property name="text">
-           <string>Select Table</string>
-          </property>
-         </item>
+         <property name="text">
+          <string>Select File</string>
+         </property>
         </widget>
        </item>
-       <item row="3" column="0">
-        <widget class="QPushButton" name="importCsvPushButton">
+       <item row="0" column="0">
+        <widget class="QPushButton" name="resetDatabasePushButton">
          <property name="minimumSize">
           <size>
-           <width>110</width>
+           <width>220</width>
            <height>0</height>
           </size>
          </property>
          <property name="text">
-          <string>Import CSV</string>
+          <string>Reset Database</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QPushButton" name="fillUserDataPushButton">
+         <property name="text">
+          <string>Fill User Table with test data</string>
          </property>
         </widget>
        </item>
@@ -78,21 +83,37 @@
          </property>
         </widget>
        </item>
-       <item row="3" column="3">
-        <widget class="QLineEdit" name="importCsvLineEdit">
+       <item row="0" column="3">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Backup current database (if exists) and create a new one from scratch.</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>Keep current database but delete entries in pilots, aircraft and flights</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1" colspan="2">
+        <widget class="QComboBox" name="tableComboBox">
          <property name="minimumSize">
           <size>
            <width>110</width>
            <height>0</height>
           </size>
          </property>
-         <property name="placeholderText">
-          <string>/path/to/file.csv</string>
-         </property>
+         <item>
+          <property name="text">
+           <string>Select Table</string>
+          </property>
+         </item>
         </widget>
        </item>
-       <item row="3" column="4">
-        <widget class="QPushButton" name="selectCsvPushButton">
+       <item row="3" column="0">
+        <widget class="QPushButton" name="importCsvPushButton">
          <property name="minimumSize">
           <size>
            <width>110</width>
@@ -100,37 +121,26 @@
           </size>
          </property>
          <property name="text">
-          <string>Select File</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="0">
-        <widget class="QPushButton" name="fillUserDataPushButton">
-         <property name="text">
-          <string>Fill User Table with test data</string>
+          <string>Import CSV</string>
          </property>
         </widget>
        </item>
-       <item row="0" column="3">
-        <widget class="QLabel" name="label">
+       <item row="2" column="3">
+        <widget class="QLabel" name="label_3">
          <property name="text">
-          <string>Backup current database (if exists) and create a new one from scratch.</string>
+          <string>Fill a new database with sample entries</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="3">
-        <widget class="QLabel" name="label_2">
+       <item row="4" column="0">
+        <widget class="QPushButton" name="debugPushButton">
          <property name="text">
-          <string>Keep current database but delete entries in pilots, aircraft and flights</string>
+          <string>Do Debug Stuff!</string>
          </property>
         </widget>
        </item>
-       <item row="2" column="3">
-        <widget class="QLabel" name="label_3">
-         <property name="text">
-          <string>Fill a new database with sample entries</string>
-         </property>
-        </widget>
+       <item row="4" column="3">
+        <widget class="QLineEdit" name="debugLineEdit"/>
        </item>
       </layout>
      </widget>

+ 1 - 6
src/gui/widgets/homewidget.cpp

@@ -17,7 +17,7 @@
  */
 #include "homewidget.h"
 #include "ui_homewidget.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 
 HomeWidget::HomeWidget(QWidget *parent) :
@@ -35,8 +35,3 @@ HomeWidget::~HomeWidget()
 {
     delete ui;
 }
-
-void HomeWidget::on_pushButton_clicked()
-{
-    // do debug stuff
-}

+ 0 - 3
src/gui/widgets/homewidget.h

@@ -48,9 +48,6 @@ public:
     explicit HomeWidget(QWidget *parent = nullptr);
     ~HomeWidget();
 
-private slots:
-    void on_pushButton_clicked();
-
 private:
     Ui::HomeWidget *ui;
 

+ 11 - 21
src/gui/widgets/homewidget.ui

@@ -27,19 +27,6 @@
      </property>
     </spacer>
    </item>
-   <item row="1" column="0">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>414</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
    <item row="1" column="1" colspan="2">
     <widget class="QStackedWidget" name="stackedWidget">
      <property name="currentIndex">
@@ -75,15 +62,18 @@
      </property>
     </spacer>
    </item>
-   <item row="3" column="1">
-    <widget class="QPushButton" name="pushButton">
-     <property name="text">
-      <string>Debug</string>
+   <item row="1" column="0">
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
      </property>
-    </widget>
-   </item>
-   <item row="4" column="1">
-    <widget class="QLineEdit" name="lineEdit"/>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>414</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
    </item>
   </layout>
  </widget>

+ 1 - 1
src/gui/widgets/logbookwidget.cpp

@@ -17,7 +17,7 @@
  */
 #include "logbookwidget.h"
 #include "ui_logbookwidget.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 LogbookWidget::LogbookWidget(QWidget *parent) :
     QWidget(parent),

+ 1 - 1
src/gui/widgets/pilotswidget.cpp

@@ -17,7 +17,7 @@
  */
 #include "pilotswidget.h"
 #include "ui_pilotswidget.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 using namespace experimental;
 PilotsWidget::PilotsWidget(QWidget *parent) :

+ 1 - 1
src/gui/widgets/settingswidget.cpp

@@ -18,7 +18,7 @@
 #include "settingswidget.h"
 #include "ui_settingswidget.h"
 #include "src/database/dbinfo.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 static const auto FIRSTNAME_VALID = QPair<QString, QRegularExpression> {
     "picfirstnameLineEdit", QRegularExpression("[a-zA-Z]+")};

+ 1 - 1
src/gui/widgets/totalswidget.cpp

@@ -1,6 +1,6 @@
 #include "totalswidget.h"
 #include "ui_totalswidget.h"
-#include "src/functions/adebug.h"
+#include "src/testing/adebug.h"
 
 TotalsWidget::TotalsWidget(QWidget *parent) :
     QWidget(parent),

+ 73 - 0
src/testing/abenchmark.cpp

@@ -0,0 +1,73 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "abenchmark.h"
+
+ABenchmark::ABenchmark()
+{
+
+}
+
+ABenchmark::ABenchmark(void (*function_one)(), void (*function_two)(), int number_of_runs)
+{
+        auto start1 = std::chrono::high_resolution_clock::now();
+        for (int i = 0; i < number_of_runs; i++) {
+            function_one();
+        }
+        auto stop1 = std::chrono::high_resolution_clock::now();
+        DEB("First Function execution finished (" << number_of_runs << " runs)");
+
+
+        auto start2 = std::chrono::high_resolution_clock::now();
+        for (int i = 0; i < number_of_runs; i++) {
+            function_two();
+        }
+        auto stop2 = std::chrono::high_resolution_clock::now();
+        DEB("Second Function execution finished (" << number_of_runs << " runs)");
+
+        DEB("Execution time for function 1: "
+            << std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()
+            << "milliseconds.");
+        DEB("Execution time for function 2: "
+            << std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()
+            << "milliseconds.");
+}
+
+ABenchmark::ABenchmark(bool (*function_one)(), bool (*function_two)(), int number_of_runs)
+{
+    auto start1 = std::chrono::high_resolution_clock::now();
+    for (int i = 0; i < number_of_runs; i++) {
+        function_one();
+    }
+    auto stop1 = std::chrono::high_resolution_clock::now();
+    DEB("First Function execution finished (" << number_of_runs << " runs)");
+
+
+    auto start2 = std::chrono::high_resolution_clock::now();
+    for (int i = 0; i < number_of_runs; i++) {
+        function_two();
+    }
+    auto stop2 = std::chrono::high_resolution_clock::now();
+    DEB("Second Function execution finished (" << number_of_runs << " runs)");
+
+    DEB("Execution time for function 1: "
+        << std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()
+        << "milliseconds.");
+    DEB("Execution time for function 2: "
+        << std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()
+        << "milliseconds.");
+}

+ 40 - 0
src/testing/abenchmark.h

@@ -0,0 +1,40 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef ABENCHMARK_H
+#define ABENCHMARK_H
+
+#include <QObject>
+#include "src/testing/adebug.h"
+
+/*!
+ * \brief The ABenchmark class provides quick access to benchmarking two functions for
+ * the purpose of performance testing.
+ *
+ */
+class ABenchmark
+{
+public:
+    ABenchmark();
+
+    ABenchmark(void (*function_one)(), void (*function_two)(), int number_of_runs);
+
+    ABenchmark(bool (*function_one)(), bool (*function_two)(), int number_of_runs);
+
+};
+
+#endif // ABENCHMARK_H

+ 1 - 2
src/functions/adebug.h → src/testing/adebug.h

@@ -3,8 +3,7 @@
 
 #include <QDebug>
 
-// Debug Makro
 #define DEB(expr) \
     qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
 
-#endif // ADEBUG_H
+#endif

+ 58 - 0
src/testing/atimer.cpp

@@ -0,0 +1,58 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "atimer.h"
+
+
+ATimer::ATimer(QObject *parent) : QObject(parent)
+{
+     start = std::chrono::high_resolution_clock::now();
+     if(parent == nullptr) {
+         qDebug() << "Starting Timer... ";
+     } else {
+         qDebug() << "Starting Timer for: " << parent->objectName();
+     }
+
+}
+
+ATimer::~ATimer()
+{
+    stop = std::chrono::high_resolution_clock::now();
+    if(parent() == nullptr) {
+        qDebug() << "Execution time: "
+                 << std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count()
+                 << "milliseconds.";
+    } else {
+        qDebug() << "Execution time for: " << parent()->objectName() << ": "
+                 << std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count()
+                 << "milliseconds.";
+    }
+}
+
+void ATimer::timeNow()
+{
+    intermediate_point = std::chrono::high_resolution_clock::now();
+    if(parent() == nullptr) {
+        qDebug() << "Intermediate time: "
+                 << std::chrono::duration_cast<std::chrono::milliseconds>(intermediate_point - start).count()
+                 << "milliseconds.";
+    } else {
+        qDebug() << "Intermediate time for: " << parent()->objectName() << ": "
+                 << std::chrono::duration_cast<std::chrono::milliseconds>(intermediate_point - start).count()
+                 << "milliseconds.";
+    }
+}

+ 55 - 0
src/testing/atimer.h

@@ -0,0 +1,55 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef ATIMER_H
+#define ATIMER_H
+
+#include <QObject>
+#include <chrono>
+#include <QDebug>
+
+/*!
+ * \brief The ATimer class provides an easy to use performance timer.
+ *
+ * It automatically stops when going out of scope and prints the elapsed time
+ * to the console. Intermediate timings can be manually obtained with timeNow().
+ *
+ * It can be given a QObject as a parent to time its lifetime or can be used without
+ * parent in any context.
+ */
+class ATimer : public QObject
+{
+    Q_OBJECT
+public:
+    ATimer(QObject* parent = nullptr);
+    ~ATimer();
+
+    void timeNow();
+private:
+
+    std::chrono::high_resolution_clock::time_point start;
+
+    std::chrono::high_resolution_clock::time_point intermediate_point;
+
+    std::chrono::high_resolution_clock::time_point stop;
+
+    double duration;
+
+};
+
+
+#endif // ATIMER_H