Deleting QChart Causes 30+ Second Application Hang!
-
@JonB In his first post, He did
deleting the QChart deleting the QChartView Hiding chart/chartview prior to deleting Removing all series prior to deleting <===he might not have tried to block update of qchart in deletion of series. running QCoreApplication::procesEvents() before/after delete
His issue:
as it deletes, the chart loops through its update/repaint method removing one series at a time.If he is able to block update of qchart while series are deleted, one final update may be ok. I do not use QChart (not free) and am not sure if it is doable.
-
@JoeCFD
I'm still not with you. The first two lines says he deletes chart and view. I do no more or less than that in my code. It takes 6 milliseconds. He says it takes him 30 seconds. I don't know why or what other than mine he is doing or needs to do? (I checked my code with valgrind, no leaks reported.) -
@FleetingMemory
I asked you to produce a minimal example such as mine but you have not. I said earlier I was guessing 10 series to make 500,000 points. If you want help I don't see why you can't convey the necessary information, no point leaving me to create 10 series I mentioned and then say it's not the right number..... And you could always alter my code to whatever numbers you desire to test..... -
@FleetingMemory try to call
removeAllSeries() first. It seems this call will not trigger update of qchart.
and then update,
next delete chart. -
@FleetingMemory
In your first post of the steps you have tried you already includedRemoving all series prior to deleting
-
Yeah, I am going to retry in release with elapsed() to see what is going on and give more info.
Query Size 450,000 points. Spread across 12,000 series.
populating the series after query takes 2,964 milliseconds
Gets stuck on remove all series (freezes main thread), takes 35,774 milliseconds to remove -
@FleetingMemory
Yes please test. OOI how can you expect to display 12,000 series to a user, I just don't get it? -
A little more testing - I used release mode, removed all series from QChart in a QChartView after a new query is run. During this test I re-used the same QChart -- after running removeAllSeries(), I used the points from the query to generate new series and add them to the chart. Points are formatted <millis since epoch, value>. Series have OpenGL turned on in this test.
1: A Query is run, Qlist<Qlist<QPointF>> generated. I return the Query Count
2: If QChart Exists, remove all series (this I timed)
3: for each Qlist<QPointF> generate a new series with replace(), append Axes and insert into chart (this I timed)Query Size 450,000 points. Spread across 12,000 series.
populating 12,000 series after query takes 2.964 s
Gets stuck on remove all 12,000 series (freezes main thread), takes 35.774 seconds to removeQuery Size: 332,000 points
populating 10,600 series: 3.3s
populating 2nd time diff data: 3.4s
removing all series: 25.35s
removing all (2nd time diff data): 25.6sQuery Size: 247,900 points
populating 9300 series: 2.5s
removing all series: 19sQuery Size 250,000
Populating Series: 1.32 s
removing all 8,050 series: 14.33s
removing all 8,050 series (2nd run diff data): 13.4sQuery Size 223,200
Populating 8600 series: 2.4s
populating 8600 series(2nd run diff data): 2s
removing all series: 15.6s
removing all series (2nd run diff data): 15.6sQuery Size: 195,600
populating series: 1.7s
Removing 7820 series: 12.5s
removing all 7820 series (2nd run diff data): 12.9sQuery Size 158,543
populating the series after query: 0.7s
removing all 4,859 series: 4.9sQuery Size 21700
Removing 1240 series: 0.395s
populating series: 0.1sQuery Size: 9,818
populating series: 0.04s
removing all 735 series: 0.045s
removing all 735 series (2nd run diff data): 0.044sPerformance seems to get worse pretty quickly at a non-linear rate
If it helps, I am compiling this as a plugin loaded in a simple main application (though that shouldn't affect things).
I have tried with useOpenGL both on and off. As far as I can tell, it makes little difference.
The fact the removeAll/delete freezes the main thread, which essentially locks up the entire application it is running in is a huge issue for me... -
@FleetingMemory
look at source code here.
https://codebrowser.dev/qt5/qtcharts/src/charts/qchart.cpp.html
removeAllSeries func has a loop to call removeSeries(QAbstractSeries *series)
I guess it will trigger update for each removal. This is not efficient. -
@FleetingMemory
Why can't you test exactly these figures, with whatever (hopefully tiny) code you use, against the skeleton I provided? You only have to alter the two loop counters. Then people have actual code they can test, so far as I know we really don't know for sure what your code reads. I seem to have been saying/suggesting this all along. If you want people to help, or even to report a bug, we have to have a complete, minimal, reproducible example. -
@FleetingMemory I tried Jon's code with 10000 series + 10 points and tried different things:
- disable update of QChartView
- disable QChartView and QChart
- hide QChartView and QChart
before chart is deleted. Nothing helps.
However, I am able to get quick clean-up of qchartview with
chartView->setChart( new QChart() ); chart->deleteLater();
Not sure if this helps you. If this piece of code does not help, you may try to delete the chart in a thread while charview is available for other uses. I guess your app will have issue at exit.