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.
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.