diff --git a/doc/dox/jkqtplotter_usage.dox b/doc/dox/jkqtplotter_usage.dox
index 567f0e14a8..aa6e975c05 100644
--- a/doc/dox/jkqtplotter_usage.dox
+++ b/doc/dox/jkqtplotter_usage.dox
@@ -124,11 +124,46 @@
representing objects by caling JKQTPlotter::getXAxis() or JKQTPlotter::getYAxis().
- \see \ref JKQTPlotterSimpleTest and \see JKQTPlotterQtCreator
+ \see \ref JKQTPlotterSimpleTest and \see \ref JKQTPlotterQtCreator
+ \defgroup jkqtplotter_general_usage_speedplotsetup Performance Considerations when Setting up Plots
+ Many of the function in JKQTPlotter case an immediate redraw of the widget. Examples are JKQTPlott::setX(),
+ JKQTPlotter::setY(), JKQTPlotter::setAbsoluteX(), JKQTPlotter::setAbsoluteY(), JKQTPlotter::addGraph() ...
+ so if you use a combination of these while setting up your plot, it is possible to
+ cause several (rather expensive) redraws of the plot widget. Therefore you can disable this redrawing, using
+ JKQTPlotter::setPlotUpdateEnabled() and you can explicitly cause a redraw with JKQTPlotter::redrawPlot().
+ To make this process even easier to use, there is a guard helper class for this: JKQTPlotterUpdateGuard.
+
+ Here is a code example:
+
+ \code
+ {
+ JKQTPlotterUpdateGuard guard(plotter);
+ // set up plot here, e.g.
+ plotter->setX();
+ plotter->setY(); ...
+ } // Block ends and immediate plot updates are reenabled. Also JKQTPlotter::redrawPlot() is called.
+ \endcode
+
+ This code has the same effect as the long version without the guard class shown below:
+
+ \code
+ const bool wasReplotEnabled=plotter->isPlotUpdateEnabled();
+ plotter->setPlotUpdateEnabled(false);
+
+ // set up plot here, e.g.
+ plotter->setX();
+ plotter->setY(); ...
+
+ // Setup ends and immediate plot updates are reenabled. Also JKQTPlotter::redrawPlot() is called.
+ plotter->setPlotUpdateEnabled(false);
+ if (wasReplotEnabled) plotter->redrawPlot();
+ \endcode
+
+ \see JKQTPlotter::setPlotUpdateEnabled(), JKQTPlotter::redrawPlot(), JKQTPlotterUpdateGuard
\defgroup jkqtplotter_general_usage_qtcreator How to use JKQTPlotter in the Qt Form Designer
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index c2b93f8fe2..da09ba6d61 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -141,6 +141,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: added JKQTPCoordinateAxis::setRangeFixed() which disables changing the axis range (and thus the zoom)
NEW: added JKQTPCoordinateAxis::getMin() and JKQTPCoordinateAxis::getMax() getters
NEW: added example \ref JKQTPlotterUIScrollbar
+ NEW: added JKQTPlotterUpdateGuard guard class that prevents redrawing of a JKQTPlotter during the lifetime of a code block, improved documentation of speed during plot setup
JKQTMathText:
diff --git a/examples/multithreaded/README.md b/examples/multithreaded/README.md
index 560277c360..c08648b5ef 100644
--- a/examples/multithreaded/README.md
+++ b/examples/multithreaded/README.md
@@ -95,12 +95,12 @@ This test results in the following numbers (on my AMD Ryzen5 8/16-core laptop):
[comment]:RESULTS
VERSION: 5.0.0
-BUILD MODE: Debug
+BUILD MODE: Release
-SERIAL RESULTS:
runtime, overall = 7262.1ms
single runtimes = (302.5 +/- 573.2) ms
speedup = 1.00x
threads / available = 1 / 16
+SERIAL RESULTS:
runtime, overall = 8283.1ms
single runtimes = (345.0 +/- 957.8) ms
speedup = 1.00x
threads / available = 1 / 16
PARALLEL RESULTS:
-runtime, overall = 896.4ms
single runtimes = (259.4 +/- 55.2) ms
speedup = 6.95x
threads / available = 8 / 16
batch runs = 3
speedup vs. serial = 8.1x
+runtime, overall = 727.0ms
single runtimes = (201.8 +/- 46.1) ms
speedup = 6.66x
threads / available = 8 / 16
batch runs = 3
speedup vs. serial = 11.4x
[comment]:RESULTS_END
diff --git a/lib/jkqtplotter/jkqtplotter.cpp b/lib/jkqtplotter/jkqtplotter.cpp
index 78dfbd1b35..9568cc3a44 100644
--- a/lib/jkqtplotter/jkqtplotter.cpp
+++ b/lib/jkqtplotter/jkqtplotter.cpp
@@ -2004,3 +2004,40 @@ void JKQTPlotter::MouseDragAction::clear()
modifier=Qt::NoModifier;
mouseButton=Qt::LeftButton;
}
+
+JKQTPlotterUpdateGuard::JKQTPlotterUpdateGuard(JKQTPlotter *plot, bool forceRedraw):
+ m_plot(plot), m_oldEnabled(true), m_forceRedraw(forceRedraw)
+{
+ if (m_plot) {
+ m_oldEnabled=m_plot->isPlotUpdateEnabled();
+ m_plot->setPlotUpdateEnabled(false);
+ }
+}
+
+JKQTPlotterUpdateGuard::~JKQTPlotterUpdateGuard() {
+ release(m_forceRedraw);
+}
+
+JKQTPlotterUpdateGuard::JKQTPlotterUpdateGuard(JKQTPlotterUpdateGuard &&other):
+ m_plot(other.m_plot), m_oldEnabled(other.m_oldEnabled), m_forceRedraw(other.m_forceRedraw)
+{
+ other.m_plot=nullptr;
+}
+
+JKQTPlotterUpdateGuard &JKQTPlotterUpdateGuard::operator=(JKQTPlotterUpdateGuard &&other) {
+ m_plot=other.m_plot;
+ m_oldEnabled=other.m_oldEnabled;
+ m_forceRedraw=other.m_forceRedraw;
+ other.m_plot=nullptr;
+ return *this;
+}
+
+void JKQTPlotterUpdateGuard::release(bool forceRedraw) {
+ if (m_plot) {
+ m_plot->setPlotUpdateEnabled(m_oldEnabled);
+ if (m_oldEnabled || forceRedraw) {
+ m_plot->redrawPlot();
+ }
+ }
+ m_plot=nullptr;
+}
diff --git a/lib/jkqtplotter/jkqtplotter.h b/lib/jkqtplotter/jkqtplotter.h
index 4da89d5f27..827bd6a82c 100644
--- a/lib/jkqtplotter/jkqtplotter.h
+++ b/lib/jkqtplotter/jkqtplotter.h
@@ -72,11 +72,21 @@ JKQTPLOTTER_LIB_EXPORT void initJKQTPlotterResources();
* \tableofcontents
*
*
+ *
+ *
* \section JKQTPLOTTER_BASICUSAGE Basic Usage of JKQTPlotter
*
* \copydetails jkqtplotter_general_usage_jkqtplotter
*
*
+ *
+ *
+ * \section JKQTPLOTTER_PERFORMACEWHILESETUP Performance Considerations when Setting up Plots
+ *
+ * \copydetails jkqtplotter_general_usage_speedplotsetup
+ *
+ *
+ *
* \section JKQTPLOTTER_SYNCMULTIPLOT Synchronizing Several Plots
*
* Often a single plot is not sufficient, but several plots need to be aligned with respect to each other:
@@ -637,7 +647,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
bool isPlotUpdateEnabled() const;
/** \brief sets whether automatic redrawing the plot is currently activated (e.g. you can sett his to \c false while performing major updates on the plot)
*
- * \see isPlotUpdateEnabled()
+ * \see JKQTPlotterUpdateGuard for a guard class coupling calls to setPlotUpdateEnabled() and redrawPlot() with the lifetime of a code block.
+ * See \ref jkqtplotter_general_usage_speedplotsetup for a detailed description.
+ * Also see isPlotUpdateEnabled().
*/
void setPlotUpdateEnabled(bool enable);
@@ -1397,7 +1409,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief indicates whether the plot is updated automatically at the moment
*
- * \see setPlotUpdateEnabled(), isPlotUpdateEnabled()
+ * \see setPlotUpdateEnabled(), isPlotUpdateEnabled(),
+ * JKQTPlotterUpdateGuard for a guard class coupling calls to setPlotUpdateEnabled() and redrawPlot() with the lifetime of a code block.
+ * See \ref jkqtplotter_general_usage_speedplotsetup for a detailed description.
*/
bool doDrawing;
@@ -1711,6 +1725,52 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
};
+
+/** \brief Guard Class (RAII construct) for JKQTPlotter that disables replotting on construction and reenables it on destruction
+ * \ingroup jkqtpplotterclasses
+ *
+ * This class can be used to forbid replotting (to improve performance) while setting up a plot.
+ * The redraw is called on destruction of the guard,i.e. typically when leaving the block that
+ * encapsulates the plot construction.
+ *
+ * \code
+ * {
+ * JKQTPlotterUpdateGuard guard(plotter);
+ *
+ * // set up plot here, e.g.
+ * plotter->setX();
+ * plotter->setY(); ...
+ * } // Block ends and immediate plot updates are reenabled. Also JKQTPlotter::redrawPlot() is called.
+ * \endcode
+ *
+ * \see JKQTPlotter::setPlotUpdateEnabled(), JKQTPlotter::redrawPlot()
+ * \see JKQTPlotterUpdateGuard for a guard class coupling calls to setPlotUpdateEnabled() and redrawPlot() with the lifetime of a code block.
+ * See \ref jkqtplotter_general_usage_speedplotsetup for a detailed description.
+ */
+class JKQTPLOTTER_LIB_EXPORT JKQTPlotterUpdateGuard {
+public:
+ JKQTPlotterUpdateGuard(JKQTPlotter* plot, bool forceRedraw=false);
+
+ ~JKQTPlotterUpdateGuard();
+
+ JKQTPlotterUpdateGuard(const JKQTPlotterUpdateGuard&)=delete;
+ JKQTPlotterUpdateGuard& operator=(const JKQTPlotterUpdateGuard&)=delete;
+ JKQTPlotterUpdateGuard(JKQTPlotterUpdateGuard&& other);
+ JKQTPlotterUpdateGuard& operator=(JKQTPlotterUpdateGuard&& other);
+
+ /** \brief release the lock, if \a forceRedraw equals \c true JKQTPlotter::redrawPlot() is called in any case,
+ * if it is \c false, JKQTPlotter::redrawPlot() is called only if JKQTPlotter::isPlotUpdateEnabled() was \c true
+ * on construction of the guard */
+ void release(bool forceRedraw=false);
+private:
+ JKQTPlotter* m_plot;
+ bool m_oldEnabled;
+ bool m_forceRedraw;
+};
+
+
+
+
QT_BEGIN_NAMESPACE
/** \brief qHash-variant used by JKQTPlotter