QTableView -> optimize performance
-
Ok, i managed to increase the performance of my QTableView instances significantly by putting some variables into private data fields via the constructor, which have been determined on the fly in data().
Anyway, it could be faster still, i guess, if i could find a way to avoid iterating in data(). I still need to do it, because as data source i'm using a list of json objects (i.e.: {key0 : value0, key1 : value1, ...}, {key0 : value0, key1 : value1, ...}), which should be displayed per row, each key being the head of one column, without knowing exactly how many key-value-pairs are in the object and of which data type. At least i'd like to have the possibility to remove or add some key value pairs without having to rewrite the code of the project.
-
@andi456 said in QTableView -> optimize performance:
way to avoid iterating in data()
Your really should avoid this - use a proper structure... simply put your data in a vector and you don't have any problems anymore.
-
I found this YouTube video from KDAB on how to write a Qt model very helpful when I implemented my first model
-
Ok, i managed to increase the performance of my QTableView instances significantly by putting some variables into private data fields via the constructor, which have been determined on the fly in data().
Anyway, it could be faster still, i guess, if i could find a way to avoid iterating in data(). I still need to do it, because as data source i'm using a list of json objects (i.e.: {key0 : value0, key1 : value1, ...}, {key0 : value0, key1 : value1, ...}), which should be displayed per row, each key being the head of one column, without knowing exactly how many key-value-pairs are in the object and of which data type. At least i'd like to have the possibility to remove or add some key value pairs without having to rewrite the code of the project.
@andi456
If from what you are saying you have JSON objects and you seem to be iterating stuff like keys in them in order to satisfydata()
requests, perhaps you should "unpack" them into C++ (if that's what you're using, you don't say) objects for faster access. You can wait until needed and cache results for performance. Or sometimes it pays to do processing work initially when new data arrives rather than each time upon retrieval. -
@andi456
If from what you are saying you have JSON objects and you seem to be iterating stuff like keys in them in order to satisfydata()
requests, perhaps you should "unpack" them into C++ (if that's what you're using, you don't say) objects for faster access. You can wait until needed and cache results for performance. Or sometimes it pays to do processing work initially when new data arrives rather than each time upon retrieval.@JonB Yes, that's what I essentially did in order to have a usable program: I copied the json object (I use nlohmann::json, because I did not know about QJson), into a two-dimensional std::vector of a custom struct and store it in a member of the model:
struct value_struct { bool string_set; std::string s; bool number_set; int n; bool flag_set; bool flag; };
The ..._set boolean values indicate which data type should be displayed in the data() method, which seems to work a lot better than my approach before. Anyway, running it in debug mode is still a little bit too slow. One obvious improvement would be to store QString values instead of std::string, but i don't know if that makes a huge difference.
-
Lifesaver when writing a model: https://wiki.qt.io/Model_Test
-
Lifesaver when writing a model: https://wiki.qt.io/Model_Test
@VRonin Ok, but it doesn't do performance checking, does it?
I did not know before, that the data() function is called in such high frequency. That's why I did not pay too much attention avoiding any unnecessary calculations, but was focused on getting it to work. Strangely enough, the performance improvement i noticed by moving some of the variables into the model's constructor and storing them in members was much bigger than my last step of copying the whole json object into a member of the model class.
-
Just a few furhter notes on observations that i made regarding QTableView performance:
1.) It is terribly slow in qtcreator default debug mode even if the cells do not contain any data at all, although i wouldn't have thought that a maximum of 70 rows x 16 columns with - I repeat - no data in it could be a problem for a modern computer even in debug mode. (I incidentally put !isValid() at the beginning of the data() method that accordingly it did not even try to put out data into the cells.)
2.) In the release mode offered by qtcreator after correcting my above error it seems to be quite snappy. The application uses a number of QTabWidget instances which are determined reading a json file via nlohmann::json for displaying the corresponding number of QTableView instances. The tables seem to appear immediately, when clicking on a tab. But making use of the "horizontalHeader()->setSectionsMovable()" feature slows down the creation of a table quite a bit.
3.) Given the above points, I wonder, Giuseppe D'Angelo in the video linked to above by DerReisende could be so confident that even much larger data sets would pose no problem?
-
As we already said - we've no problems with 10k of rows in a QTableView. Provide a minimal, compilable example to reproduce the problem.
-
As we already said - we've no problems with 10k of rows in a QTableView. Provide a minimal, compilable example to reproduce the problem.
@Christian-Ehrlicher Well, the program works much better than before. Anyway, I'll start from scratch with only one table and see what happens and will thus provide a minimal example.
My guess right now is that deciding which data type (number, boolean, string) to use in data() is the bottleneck. Could I just put the json values into a QVariant?
-
@Christian-Ehrlicher Well, the program works much better than before. Anyway, I'll start from scratch with only one table and see what happens and will thus provide a minimal example.
My guess right now is that deciding which data type (number, boolean, string) to use in data() is the bottleneck. Could I just put the json values into a QVariant?
@andi456 Found my mistake, it was a bad design decision by me, because I did not know how the data() function works. I realized this, because nlohmann/json.hpp should indeed provide fast access, while not being the fastest parser around, and the performance being slow without any data being displayed.
I can now confirm, that the mentioned json-class is sufficiently fast to be used in the view/model framework.