Spending an awful lot of time in data() for not much happening on screen.
-
I have a QTreeView with some, but not lots and lots, of values to show on screen. I have been profiling my code and an awful lot of time seems to be spent in data() ; that is, something is querying the model for information an awful lot. I am coming around to suspecting that as the model is updated (and this happens possibly tens of thousands of times per user-driven event) the QTreeView that is displaying the model is asking for the data alot more than I want.
Is it possible that every time the model is changing, the QTreeView is fetching all the data again? I suspect this based on the existence of the dataChanged function, @QAbstractItemView::dataChanged@
The documentation states this function is called every time the model changes, although it does not say what the function actually does, if anything. I went to the source
where I see that it does indeed do something, so maybe this is being called every time the model changes and thus I'm getting tens-of-thousands of calls to this function as the QTreeView valiantly tries to keep up-to-date with the model. I must say that since it looks like it contains branches to decide if an update is needed or not, I suspect it's not spending much time in here if it is getting in here.
I'd really rather it didn't; I'd like it to wait until the updating is finished.
I'm at about the limit of my knowledge; can anyone elucidate on my working theory above, and suggest how I can be sure that this is (or is not) what is happening? And if it is happening, how I can fix it. I think I could manage disconnecting the signal from the slot and then reconnecting it after the model has finished being updated.
-
Hi,
Generally speaking, when dealing with a model that get lots of updates, the common practice is to "batch update" the model and send dataChanged less frequently e.g. each 1000 updates done.
Hope it helps
-
Aha. That could well help, thank you. How's this commonly done? Do people disconnect the dataChanged signal and then turn it back on again? If I understand it correctly, right now every single change to the model causes a dataChanged signal, so to do a 1000 updates without this I'd need to disconnect the signal.
-
For our QAbstractListModel, we call beginResetModel() and endResetModel() before and after adding the data.
-
Ah. Looks like that's already being done, sadly (as you might have guessed from my uncertainty about what it's all doing, I'm maintainer/expander on this set of code rather than original developer(s), who are unavailable for business reasons).
In terms of performance analysis, I've done a run with perf and built one of those cool-looking flamegraphs; I'll have to go digging through that and see if I can figure out just what's eating all my time.
I do appreciate the posts very much, though; this is the kind of discussion that really fills in the gaps for me - reading the manuals and experimenting with the code is a good way to learn, but there's no substitute for experienced advice.
-
What kind of model is being used ? And how is the data inserted in the model ?
Also, do you have an underlying data structure that is made available through this model ? -
These are excellent questions; I freely admit that I've got a little trouble answering them, as the actual underlying model and the means by which information is pushed into it are somewhat obscured. Someone clever must have written the original code. I don't want to give wrong answers, so I'll go looking; I have found them in the past, I just don't recall off the top of my head what they were.