From 98c3bb8aee98c289342698d7adf86b4ae31ade29 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 29 Dec 2020 10:15:38 -0500 Subject: [PATCH] Add a pyqtgraph profiling toggle to chart CLI --- piker/__init__.py | 3 ++- piker/_profile.py | 8 ++++++++ piker/ui/_chart.py | 1 - piker/ui/_graphics/_curve.py | 6 ++++-- piker/ui/_graphics/_ohlc.py | 11 +++-------- piker/ui/cli.py | 15 ++++++++++++--- 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/piker/__init__.py b/piker/__init__.py index 92553306..75ec8ded 100644 --- a/piker/__init__.py +++ b/piker/__init__.py @@ -1,5 +1,5 @@ # piker: trading gear for hackers. -# Copyright 2018 Tyler Goodlet +# Copyright 2020-eternity Tyler Goodlet (in stewardship for piker0) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -16,6 +16,7 @@ """ piker: trading gear for hackers. + """ import msgpack # noqa import msgpack_numpy diff --git a/piker/_profile.py b/piker/_profile.py index a6f171c1..fa38d065 100644 --- a/piker/_profile.py +++ b/piker/_profile.py @@ -16,10 +16,18 @@ """ Profiling wrappers for internal libs. + """ import time from functools import wraps +_pg_profile: bool = False + + +def pg_profile_enabled() -> bool: + global _pg_profile + return _pg_profile + def timeit(fn): @wraps(fn) diff --git a/piker/ui/_chart.py b/piker/ui/_chart.py index 61669be3..92eed5d2 100644 --- a/piker/ui/_chart.py +++ b/piker/ui/_chart.py @@ -1068,7 +1068,6 @@ async def chart_from_quotes( mn_in_view = min(price, mn_in_view) if mx_in_view > last_mx or mn_in_view < last_mn: - print('scaling') chart._set_yrange(yrange=(mn_in_view, mx_in_view)) last_mx, last_mn = mx_in_view, mn_in_view diff --git a/piker/ui/_graphics/_curve.py b/piker/ui/_graphics/_curve.py index b64d6f51..9e6d08e6 100644 --- a/piker/ui/_graphics/_curve.py +++ b/piker/ui/_graphics/_curve.py @@ -22,6 +22,8 @@ from typing import Tuple import pyqtgraph as pg from PyQt5 import QtCore, QtGui +from ..._profile import pg_profile_enabled + class FastAppendCurve(pg.PlotCurveItem): @@ -46,7 +48,7 @@ class FastAppendCurve(pg.PlotCurveItem): y, ) -> QtGui.QPainterPath: - profiler = pg.debug.Profiler(disabled=True) + profiler = pg.debug.Profiler(disabled=not pg_profile_enabled()) flip_cache = False # print(f"xrange: {self._xrange}") @@ -139,7 +141,7 @@ class FastAppendCurve(pg.PlotCurveItem): def paint(self, p, opt, widget): - profiler = pg.debug.Profiler(disabled=True) + profiler = pg.debug.Profiler(disabled=not pg_profile_enabled()) # p.setRenderHint(p.Antialiasing, True) p.setPen(self.opts['pen']) diff --git a/piker/ui/_graphics/_ohlc.py b/piker/ui/_graphics/_ohlc.py index d3fcb59d..e96aae90 100644 --- a/piker/ui/_graphics/_ohlc.py +++ b/piker/ui/_graphics/_ohlc.py @@ -25,9 +25,9 @@ from numba import jit, float64, int64 # , optional from PyQt5 import QtCore, QtGui from PyQt5.QtCore import QLineF, QPointF # from numba import types as ntypes -# from .._profile import timeit # from ..data._source import numba_ohlc_dtype +from ..._profile import pg_profile_enabled from .._style import hcolor @@ -141,14 +141,13 @@ def path_arrays_from_ohlc( return x, y, c -# @timeit def gen_qpath( data, start, # XXX: do we need this? w, ) -> QtGui.QPainterPath: - profiler = pg.debug.Profiler(disabled=True) + profiler = pg.debug.Profiler(disabled=not pg_profile_enabled()) x, y, c = path_arrays_from_ohlc(data, start, bar_gap=w) profiler("generate stream with numba") @@ -207,7 +206,6 @@ class BarItems(pg.GraphicsObject): self.start_index: int = 0 self.stop_index: int = 0 - # @timeit def draw_from_data( self, data: np.ndarray, @@ -238,7 +236,6 @@ class BarItems(pg.GraphicsObject): return self.path - # @timeit def update_from_array( self, array: np.ndarray, @@ -342,10 +339,9 @@ class BarItems(pg.GraphicsObject): if flip_cache: self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache) - # @timeit def paint(self, p, opt, widget): - profiler = pg.debug.Profiler(disabled=False) # , delayed=False) + profiler = pg.debug.Profiler(disabled=not pg_profile_enabled()) # , delayed=False) # p.setCompositionMode(0) p.setPen(self.bars_pen) @@ -362,7 +358,6 @@ class BarItems(pg.GraphicsObject): p.drawPath(self.path) profiler('draw history path') - # @timeit def boundingRect(self): # Qt docs: https://doc.qt.io/qt-5/qgraphicsitem.html#boundingRect diff --git a/piker/ui/cli.py b/piker/ui/cli.py index 0b2422da..e14ef3f6 100644 --- a/piker/ui/cli.py +++ b/piker/ui/cli.py @@ -84,7 +84,7 @@ def monitor(config, rate, name, dhost, test, tl): @cli.command() -@click.option('--tl', is_flag=True, help='Enable tractor logging') +# @click.option('--tl', is_flag=True, help='Enable tractor logging') @click.option('--date', '-d', help='Contracts expiry date') @click.option('--test', '-t', help='Test quote stream file') @click.option('--rate', '-r', default=1, help='Logging level') @@ -121,16 +121,25 @@ def optschain(config, symbol, date, tl, rate, test): @cli.command() +@click.option( + '--profile', + is_flag=True, + help='Enable pyqtgraph profiling' +) @click.option('--date', '-d', help='Contracts expiry date') @click.option('--test', '-t', help='Test quote stream file') @click.option('--rate', '-r', default=1, help='Logging level') @click.argument('symbol', required=True) @click.pass_obj -def chart(config, symbol, date, rate, test): - """Start an option chain UI +def chart(config, symbol, date, rate, test, profile): + """Start a real-time chartng UI """ + from .. import _profile from ._chart import _main + # possibly enable profiling + _profile._pg_profile = profile + # global opts brokername = config['broker'] tractorloglevel = config['tractorloglevel']