Comments (12)
the bottleneck should be the number shown not the number present overall
Exactly.
I'm short on time at the moment, but yes I will profile both backends, probably next week, with priority given to the Qt backend. Except if someone wants to take a stab at it in the meantime ;)
from mne-qt-browser.
I think it depends on how much faster (2) was. If we're talking (1) as being < 100 us faster than (2) for common use cases, it doesn't matter and we should use (2) all the time.
But a less invasive change is probably to continue with (2) but setVisible(False)
all annotations. First we should make sure this alleviates the bottleneck (it should, but we should check). Then we use NumPy vectorized math to figure out which annotations are in a specific window/view (fast) and setVisible(False)
the set of annotations that were shown in the previous view, and .setVisible(True)
the annotations visible in the new view. I don't think this will add much complexity -- I'll give it a try hopefully this week.
from mne-qt-browser.
I took a very quick look through the codebase today, and one potential bottleneck is the (numerous) for loops on the entire set of AnnotRegion
in self.mne.regions
. e.g. this one which seems to toggle them visible/not visible:
mne-qt-browser/mne_qt_browser/_pg_figure.py
Lines 4105 to 4109 in 72fb369
Instead, looping on the regions
in the current view would be faster, but we need to keep track of the onset/offset of each region to be able to use some numpy
math to select the annotations in the current view.
from mne-qt-browser.
What is the performance of the Matplotlib-based browser in these cases?
from mne-qt-browser.
It does suffer heavily as well. 1-2 seconds between horizontal scroll.
from mne-qt-browser.
Agreed we should optimize this, the bottleneck should be the number shown not the number present overall. Can you line profile to figure out the issue or want some help? If the latter, if you could recreate this issue with sample
(e.g., by adding 1000 0.1 sec annotations or whatever) I can look
from mne-qt-browser.
... if you've never line profiled and want to try, this is what I suggested in another thread:
mne-tools/mne-bids-pipeline#609 (comment)
it's fun :)
from mne-qt-browser.
I know this is the wrong repository, but while someone is already profiling, could we also take a look at the Matplotlib backend?
from mne-qt-browser.
In early development, I benchmarked multiple ways of updating the shown annotations in Qt for best scroll performance:
- Only add AnnotRegion (which is a child of pyqtgraph's LinearRegionItem, which handles drawing with QPainter.drawRect) to the PlotItem (which manages adding QGraphicsItems to the QGraphicsScene) when in shown time range.
- Always add all AnnotRegions for all annotations from the file to PlotItem.
1.
had the advantage of being more scalable, but 2.
was faster for common amounts of annotations so we discussed the most common usecase and went for 2.
as the current solution. With large amounts of AnnotRegions added to the PlotItem, even the Qt probably struggles under the hood with that many items to be drawn or not drawn in the current viewing window.
As part of a solution we could reimplement solution 1.
above a yet to be determined limit of no. annotations.
But this would still not speed up the second usecase you describe, when you want to improve speed for drawing a lot of annotations on the screen. Maybe creating our own implementation of a Rectangle-Class with calling directly QPainter.drawRect might reduce a bit of overhead from pyqtgraph. But I doubt it would speed up drawing much, since the guys from pyqtgraph usually already did a good job in optimizing performance. I think the bottleneck is the qt-backend there. Considering an alternative backend like vispy might be an option for the future. But that would require a new backend adaption, since the code here relies heavily on pyqtgraph and the Qt-API.
from mne-qt-browser.
I just found py-spy, a very low-overhead line profiler with nice outputs (flame graphs etc.). It might be worth a try.
from mne-qt-browser.
Okay on macOS with:
$ root# HOME=/Users/larsoner MNE_DATASETS_SAMPLE_PATH="/Users/larsoner/mne_data" py-spy top -s -r 1000 -- python -u /Users/larsoner/Desktop/rep.py 10000
Collecting samples from 'python -u /Users/larsoner/Desktop/rep.py 10000' and subprocesses
Total Samples 41950
GIL: 72.90%, Active: 100.00%, Threads: 1, Processes 1
%Own %Total OwnTime TotalTime Function (filename)
0.00% 0.00% 0.000s 40.99s <module> (rep.py)
0.00% 0.00% 0.000s 37.03s plot_raw (<decorator-gen-199>)
0.00% 0.00% 0.000s 37.03s plot_raw (mne/viz/raw.py)
0.00% 0.00% 0.000s 37.03s plot (mne/io/base.py)
0.00% 0.00% 0.000s 37.02s _get_browser (mne/viz/_figure.py)
0.00% 0.00% 0.000s 33.31s _init_browser (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.001s 33.12s func (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.273s 33.12s __init__ (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.026s 25.34s _init_annot_mode (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.305s 20.03s _add_region (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.009s 10.35s __iter__ (mne/annotations.py)
0.00% 0.00% 0.086s 10.34s __getitem__ (mne/annotations.py)
0.00% 0.00% 2.81s 10.23s _any_ch_names (mne/annotations.py)
0.00% 0.00% 3.33s 8.91s addItem (pyqtgraph/graphicsItems/PlotItem/PlotItem.py)
0.00% 0.00% 7.42s 7.42s <genexpr> (mne/annotations.py)
0.00% 0.00% 0.252s 7.23s update_annotations (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.316s 6.84s _get_color (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.113s 5.94s update_color (mne_qt_browser/_pg_figure.py)
0.00% 0.00% 0.073s 5.58s addItem (pyqtgraph/graphicsItems/ViewBox/ViewBox.py)
0.00% 0.00% 1.18s 5.56s itemChange (pyqtgraph/graphicsItems/GraphicsObject.py)
...
We have some good candidates for speedups. I'll see what I can do...
from mne-qt-browser.
... and based on the addItem
being a bottleneck, I think adding all then hiding the not-shown won't fix the problem. I think we need to dynamically add and remove. It looks like this is already done in the AnnotationBar actually, so hopefully we can re-use some code somehow.
from mne-qt-browser.
Related Issues (20)
- Benchmark data not available
- Possibility to remove mne-qt-browser splash screen HOT 4
- Plot window is blank and freezes (not responding) when launched in PyCharm's Python console or debugger HOT 6
- BUG: Use of deprecated function HOT 1
- Index bug when annotating segments in data browser HOT 5
- Changing color/thickness of vline appearing on signal plot? HOT 2
- _overview_radio_clicked() takes 1 positional argument but 2 positional arguments were given HOT 3
- channel selection does not work in raw.plot HOT 2
- mne not recognising mne-qt-browser version for epochs instance HOT 4
- Filter, scrolling, whitening are not playing nicely together HOT 1
- [ENH] Make it possible to toggle visibility of bad channels, especially in butterfly mode HOT 7
- MAINT: Use black
- Update projectors when bad channels are selected/unselected HOT 1
- ENH: framework for drawing channel-specific annotations interactively HOT 5
- Q: Release? HOT 4
- Annotation labels should not (or not only) appear in the center of the annotation HOT 4
- MNT: Add issue-forms with YAML instead of Markdown-templates HOT 5
- Crashes on macOS HOT 12
- MNE-Qt-Browser hijacks app icon HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mne-qt-browser.