Skip to content

Commit 183b7b0

Browse files
committed
Added comparative benchmark: PyQwt5 vs. PythonQwt
1 parent 479ed13 commit 183b7b0

File tree

3 files changed

+154
-85
lines changed

3 files changed

+154
-85
lines changed

qwt/tests/CurveBenchmark.py

Lines changed: 80 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@
1010

1111
import time
1212
import numpy as np
13+
import sys
1314

14-
from qwt.qt.QtGui import (QApplication, QPen, QBrush, QMainWindow, QGridLayout,
15+
from qwt.qt.QtGui import (QApplication, QPen, QMainWindow, QGridLayout,
1516
QTabWidget, QWidget, QTextEdit, QLineEdit, QFont,
1617
QFontDatabase)
17-
from qwt.qt.QtCore import QSize
1818
from qwt.qt.QtCore import Qt
19-
from qwt import QwtPlot, QwtSymbol, QwtPlotCurve
19+
20+
import os
21+
if os.environ.get('USE_PYQWT5', False):
22+
USE_PYQWT5 = True
23+
from PyQt4.Qwt5 import QwtPlot, QwtPlotCurve
24+
else:
25+
USE_PYQWT5 = False
26+
from qwt import QwtPlot, QwtPlotCurve # analysis:ignore
2027

2128

2229
COLOR_INDEX = None
@@ -38,34 +45,40 @@ def __init__(self, title, xdata, ydata, style, symbol=None, *args):
3845
self.setTitle(title)
3946
self.setAxisTitle(QwtPlot.xBottom, 'x')
4047
self.setAxisTitle(QwtPlot.yLeft, 'y')
41-
curve = QwtPlotCurve()
42-
curve.setPen(QPen(get_curve_color()))
43-
curve.setStyle(style)
44-
curve.setRenderHint(QwtPlotCurve.RenderAntialiased)
45-
if symbol is not None:
46-
curve.setSymbol(symbol)
47-
curve.attach(self)
48-
curve.setData(xdata, ydata)
48+
for idx in range(1, 11):
49+
curve = QwtPlotCurve()
50+
curve.setPen(QPen(get_curve_color()))
51+
curve.setStyle(style)
52+
curve.setRenderHint(QwtPlotCurve.RenderAntialiased)
53+
if symbol is not None:
54+
curve.setSymbol(symbol)
55+
curve.attach(self)
56+
curve.setData(xdata, ydata*idx)
57+
# self.setAxisScale(self.yLeft, -1.5, 1.5)
58+
# self.setAxisScale(self.xBottom, 9.9, 10.)
4959
self.replot()
5060

5161

5262
class BMWidget(QWidget):
53-
def __init__(self, points, *args):
63+
def __init__(self, points, *args, **kwargs):
5464
super(BMWidget, self).__init__()
55-
self.setup(points, *args)
65+
self.setup(points, *args, **kwargs)
5666

57-
def params(self, *args):
58-
return (
59-
('Lines', None),
60-
('Dots', None),
61-
)
67+
def params(self, *args, **kwargs):
68+
if kwargs.get('only_lines', False):
69+
return (('Lines', None),)
70+
else:
71+
return (
72+
('Lines', None),
73+
('Dots', None),
74+
)
6275

63-
def setup(self, points, *args):
76+
def setup(self, points, *args, **kwargs):
6477
x = np.linspace(.001, 20., points)
6578
y = (np.sin(x)/x)*np.cos(20*x)
6679
layout = QGridLayout()
6780
nbcol, col, row = 2, 0, 0
68-
for style, symbol in self.params(*args):
81+
for style, symbol in self.params(*args, **kwargs):
6982
layout.addWidget(BMPlot(style, x, y, getattr(QwtPlotCurve, style),
7083
symbol=symbol), row, col)
7184
col += 1
@@ -81,50 +94,69 @@ def setup(self, points, *args):
8194

8295

8396
class BMText(QTextEdit):
84-
def __init__(self, parent=None):
97+
def __init__(self, parent=None, title=None):
8598
super(BMText, self).__init__(parent)
8699
self.setReadOnly(True)
100+
library = 'PyQwt5' if USE_PYQWT5 else 'PythonQwt'
101+
wintitle = self.parent().windowTitle()
102+
if not wintitle:
103+
wintitle = "Benchmark"
104+
if title is None:
105+
title = '%s example' % wintitle
106+
self.parent().setWindowTitle('%s [%s]' % (wintitle, library))
87107
self.setText("""\
88-
<b>Curve benchmark example:</b><br><br>
108+
<b>%s:</b><br>
109+
(base plotting library: %s)<br><br>
89110
Click on each tab to test if plotting performance is acceptable in terms of
90111
GUI response time (switch between tabs, resize main windows, ...).<br>
91112
<br><br>
92113
<b>Benchmarks results:</b>
93-
""")
114+
""" % (title, library))
94115

95116

96117
class BMDemo(QMainWindow):
118+
TITLE = 'Curve benchmark'
119+
SIZE = (1000, 800)
97120
def __init__(self, max_n, parent=None, **kwargs):
98121
super(BMDemo, self).__init__(parent=parent)
99-
self.setWindowTitle('Curve benchmark')
100-
tabs = QTabWidget()
101-
self.setCentralWidget(tabs)
102-
contents = BMText()
103-
tabs.addTab(contents, 'Contents')
104-
self.resize(1000, 600)
122+
title = self.TITLE
123+
if kwargs.get('only_lines', False):
124+
title = '%s (%s)' % (title, 'only lines')
125+
self.setWindowTitle(title)
126+
self.tabs = QTabWidget()
127+
self.setCentralWidget(self.tabs)
128+
self.text = BMText(self)
129+
self.tabs.addTab(self.text, 'Contents')
130+
self.resize(*self.SIZE)
105131

106132
# Force window to show up and refresh (for test purpose only)
107133
self.show()
108134
QApplication.processEvents()
109-
135+
110136
t0g = time.time()
137+
self.run_benchmark(max_n, **kwargs)
138+
dt = time.time()-t0g
139+
self.text.append("<br><br><u>Total elapsed time</u>: %d ms" % (dt*1e3))
140+
self.tabs.setCurrentIndex(0)
141+
142+
def process_iteration(self, title, widget, t0):
143+
self.tabs.addTab(widget, title)
144+
self.tabs.setCurrentWidget(widget)
145+
146+
# Force widget to refresh (for test purpose only)
147+
QApplication.processEvents()
148+
149+
time_str = "Elapsed time: %d ms" % ((time.time()-t0)*1000)
150+
widget.text.setText(time_str)
151+
self.text.append("<br><i>%s:</i><br>%s" % (title, time_str))
152+
153+
def run_benchmark(self, max_n, **kwargs):
111154
for idx in range(4, -1, -1):
112155
points = max_n/10**idx
113-
t0 = time.time()
114-
widget = BMWidget(points)
115156
title = '%d points' % points
116-
tabs.addTab(widget, title)
117-
tabs.setCurrentWidget(widget)
118-
119-
# Force widget to refresh (for test purpose only)
120-
QApplication.processEvents()
121-
122-
time_str = "Elapsed time: %d ms" % ((time.time()-t0)*1000)
123-
widget.text.setText(time_str)
124-
contents.append("<br><i>%s:</i><br>%s" % (title, time_str))
125-
dt = time.time()-t0g
126-
contents.append("<br><br><u>Total elapsed time</u>: %d ms" % (dt*1000))
127-
tabs.setCurrentIndex(0)
157+
t0 = time.time()
158+
widget = BMWidget(points, **kwargs)
159+
self.process_iteration(title, widget, t0)
128160

129161

130162
if __name__ == '__main__':
@@ -133,5 +165,8 @@ def __init__(self, max_n, parent=None, **kwargs):
133165
if name in QFontDatabase().families():
134166
app.setFont(QFont(name))
135167
break
136-
demo = BMDemo(1000000)
168+
kwargs = {}
169+
for arg in sys.argv[1:]:
170+
kwargs[arg] = True
171+
demo = BMDemo(1000000, **kwargs)
137172
app.exec_()

qwt/tests/CurveStyles.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,67 +9,55 @@
99
SHOW = True # Show test in GUI-based test launcher
1010

1111
import time
12+
import sys
1213

13-
from qwt.qt.QtGui import (QApplication, QPen, QBrush, QMainWindow, QTabWidget,
14-
QFont, QFontDatabase)
14+
from qwt.qt.QtGui import QApplication, QPen, QBrush, QFont, QFontDatabase
1515
from qwt.qt.QtCore import QSize
1616
from qwt.qt.QtCore import Qt
1717

1818
from qwt.tests import CurveBenchmark as cb
19-
from qwt import QwtSymbol
19+
20+
if cb.USE_PYQWT5:
21+
from PyQt4.Qwt5 import QwtSymbol
22+
else:
23+
from qwt import QwtSymbol # analysis:ignore
2024

2125

2226
class CSWidget(cb.BMWidget):
23-
def params(self, *args):
27+
def params(self, *args, **kwargs):
2428
symbols, = args
2529
symb1 = QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.yellow),
2630
QPen(Qt.blue), QSize(5, 5))
2731
symb2 = QwtSymbol(QwtSymbol.XCross, QBrush(),
2832
QPen(Qt.darkMagenta), QSize(5, 5))
2933
if symbols:
30-
return (
31-
('Sticks', symb1),
32-
('Lines', symb1),
33-
('Steps', symb2),
34-
('Dots', symb2),
35-
)
34+
if kwargs.get('only_lines', False):
35+
return (('Lines', symb1), ('Lines', symb1), ('Lines', symb2),
36+
('Lines', symb2),)
37+
else:
38+
return (('Sticks', symb1), ('Lines', symb1),
39+
('Steps', symb2), ('Dots', symb2),)
3640
else:
37-
return (
38-
('Sticks', None),
39-
('Lines', None),
40-
('Steps', None),
41-
('Dots', None),
42-
)
41+
if kwargs.get('only_lines', False):
42+
return (('Lines', None), ('Lines', None), ('Lines', None),
43+
('Lines', None),)
44+
else:
45+
return (('Sticks', None), ('Lines', None), ('Steps', None),
46+
('Dots', None),)
4347

4448

45-
class BMDemo(QMainWindow):
46-
def __init__(self, max_n, parent=None, **kwargs):
47-
super(BMDemo, self).__init__(parent=parent)
48-
self.setWindowTitle('Curve styles')
49-
tabs = QTabWidget()
50-
self.resize(1000, 800)
51-
52-
# Force window to show up and refresh (for test purpose only)
53-
self.show()
54-
QApplication.processEvents()
49+
class BMDemo(cb.BMDemo):
50+
TITLE = 'Curve styles'
51+
SIZE = (1000, 800)
5552

56-
self.setCentralWidget(tabs)
57-
pts = 1000
58-
for points, symbols in zip((pts/10, pts/10, pts, pts),
53+
def run_benchmark(self, max_n, **kwargs):
54+
for points, symbols in zip((max_n/10, max_n/10, max_n, max_n),
5955
(True, False)*2):
6056
t0 = time.time()
61-
widget = CSWidget(points, symbols)
6257
symtext = "with%s symbols" % ("" if symbols else "out")
6358
title = '%d points, %s' % (points, symtext)
64-
tabs.addTab(widget, title)
65-
tabs.setCurrentWidget(widget)
66-
67-
# Force widget to refresh (for test purpose only)
68-
QApplication.processEvents()
69-
70-
time_str = "Elapsed time: %d ms" % ((time.time()-t0)*1000)
71-
widget.text.setText(time_str)
72-
tabs.setCurrentIndex(0)
59+
widget = CSWidget(points, symbols, **kwargs)
60+
self.process_iteration(title, widget, t0)
7361

7462

7563
if __name__ == '__main__':
@@ -78,5 +66,8 @@ def __init__(self, max_n, parent=None, **kwargs):
7866
if name in QFontDatabase().families():
7967
app.setFont(QFont(name))
8068
break
81-
demo = BMDemo(100000)
69+
kwargs = {}
70+
for arg in sys.argv[1:]:
71+
kwargs[arg] = True
72+
demo = BMDemo(1000, **kwargs)
8273
app.exec_()
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Licensed under the terms of the MIT License
4+
# Copyright (c) 2015 Pierre Raybaut
5+
# (see LICENSE file for more details)
6+
7+
"""
8+
PyQwt5 vs. PythonQwt
9+
====================
10+
"""
11+
12+
import os
13+
import os.path as osp
14+
import sys
15+
import subprocess
16+
import time
17+
18+
19+
def run_script(filename, args=None, wait=True):
20+
"""Run Python script"""
21+
os.environ['PYTHONPATH'] = os.pathsep.join(sys.path)
22+
23+
command = [sys.executable, '"'+filename+'"']
24+
if args is not None:
25+
command.append(args)
26+
proc = subprocess.Popen(" ".join(command), shell=True)
27+
if wait:
28+
proc.wait()
29+
30+
31+
def main():
32+
for name in ('CurveBenchmark.py', 'CurveStyles.py',):
33+
for args in (None, 'only_lines'):
34+
for value in ('', '1'):
35+
os.environ['USE_PYQWT5'] = value
36+
filename = osp.join(osp.dirname(osp.abspath(__file__)), name)
37+
run_script(filename, wait=False, args=args)
38+
time.sleep(4)
39+
40+
41+
if __name__ == '__main__':
42+
main()
43+

0 commit comments

Comments
 (0)