Is QSettings::setValue costly
-
In my application I have a
QTableWidget
where each row holds some info that need to be saved and a lot of operations can be done in the table, like adding mutiple rows, deleting multiple row.Right now every time the table changes I call the function saveSettings, in that function I have about 15
setValue
operations and abeginWriteArray
that can theoretically have any number in size and each iteration has 5setValue
operations .I want to know if that is too costly in terms of performance or is it a trivial operation(which I think it is but I am not sure and couldn't find nothing about that in the doc), should I call saveSettings only in the closeEvent function?
-
Hi,
That will depend on your OS, cache and hard drive.
The first thing to do is to ask yourself: does it make sense to save the state after each operation ?
Do you allow undo/redo ?In any case, when in doubt: benchmark it.
-
does it make sense to save the state after each operation ?
Yes, that would be for cases where the application or crashes(hopefully it will not) the user won't lose the data it has in the table
Do you allow undo/redo ?
No
In any case, when in doubt: benchmark it.
How do I do that?
-
@hbatalha
To answer your original question.QSettings::setValue()
is not in itself as "expensive" as you might think. Unless you goQSettings::sync()
, changes are buffered in memory and only sent to disk/storage intermittently from the event loopThis function is called automatically from QSettings's destructor and by the event loop at regular intervals
So e.g. if you do 100
setValue()s
in a row one immediately after the other, this will only do one save-to-disk.Having said that, I would not be saving "thousands" of entries into a
QSettings()
. If, say, you are using Windows registry for your settings, go look see how many other applications save "thousands" of separate entries in the registry? And if you are using a.ini
file to save (Windows, or Linux), any change to any one item will result in have to rewrite the entire file anyway. I cannot imagine how/what you have "thousands" of in a UI to save. If you are going to be saving to ini file I would consider, say, storing the whole thing as a single JSON string. -
-
@hbatalha
I still meant saving to the.ini
/registry, not creating some separate file. I just meant: rather than 1,000 separate subkeys for each item, save a JSON of all the data under one key.I outlined earlier the pros & cons, e.g. this would be potentially slower to save when using Windows registry, but OTOH it would not create thousands of registry keys, which probably has its own overheads/drawbacks.
I don't know what you are saving, or why you would be saving thousands of items, without having, say, a database behind it.
-
Might be an odd question but does it need to be QTableWidget? Unless you put some odd data types in it (but you're saving in QSettings so I doubt) much faster approach would be QTableView with QSqlTableModel and backend in SQlite (which you can construct as in memory or as a file on disk).
-
I don't know what you are saving,
I am just saving basic/common settings like "confirm on exit, theme, language", a total of 11 of those kind of settings and then the "user defined" ones. These settings are save the state(rows, rows items etc) of the QTableWidget so the it brings it up on start, each row has 5 settings to set but the number of rows is up to the user.
or why you would be saving thousands of items
As developers we should never assume what the actions of the user towards the software we create will be but I can't possibly imagine a user reaching a thousand rows or performing thousands of operations but hey, users are unpredictable.
With that being said and all that is been said in the post I am leaving the code as it is for, calling saveSettings on every operation the user performs on the table with the belief that it will not affect performance. I will later write a benchmarck as suggested by @SGaist and as suggested by @SGaist I have the option to implement the auto-save.
-
@artwaw said in Is QSettings::setValue costly:
Might be an odd question but does it need to be QTableWidget?
Pretty good question! Before this project the only app I created in Qt was a calculator, introducing me only to connect mechanisms, QPushButton, QTextEdit etc, basic things. With this project I am learning as I am going, and thanks to this forum, it's been very smooth, it is really making learning Qt pretty easy for me.
When I first needed to create a table on my app the first thing that showed when I googled was QTableWidget so I went and learnt about it, implemented for my app needs and it worked fine.
Only later on I learned about the existence of Model/View Programming and the QTableView. I went and read the documentation and in that time with much less knowledge of Qt than I have now it seemed pretty daunting to me, and as I had a working QTableWidget code that was doing everything I needed I decided to go with it and leave QTableView for the next project.
As a beginner I think working with QTableWidget will be good for the learning experience.with QSqlTableModel and backend in SQlite
My app doesn't require a database.
-
@hbatalha said in Is QSettings::setValue costly:
My app doesn't require a database.
a user reaching a thousand rows or performing thousands of operations but hey, users are unpredictable.
It possibly does --- like a lightweight one as suggested by @artwaw --- given the number of items you seem to be talking about.
Only later on I learned about the existence of Model/View Programming and the QTableView.
This may be the crux. I would be looking at saving the model. From that you should be able to recreate whatever you need. And I wouldn't be picking
QSettings
for saving a model.But of course as you please, or for a future development.
-
@JonB said in Is QSettings::setValue costly:
This may be the crux. I would be looking at saving the model.
yeah I tried that but it doesn't work, we had this discussion here , and the conclusion reached was that I am better off using
QSettings
. -
@hbatalha I went through linked topic and still fail to see why simple sqlite db would not work (and be a lot simpler to that).
You have push buttons there, value of push button can be saved as bool or int to the model.
Usual model/view approach here would be to:- have backend in slite;
- linked with a QSqlTableModel or a class derived from it;
- linked with QTableView for display
Drawing of buttons should be done through a delegate (a delegate type can be assign per column) which should handle not only drawing a buttons but also interactions, whatever you want them to be, as delegate is the the thing in the middle between the view and the model that handles a lot of things with regards to user interaction.
This might require some re-thinking of internal structures and flow but in the end it should result in your program being robust, memory efficient and fast.
-
@artwaw wow thanks for the detailed explanation. Actually I have already deployed my program ( in windows, in linux is proving to be a struggle ) and have sent it to some of my friends so they can give me a feedback, identify bugs, well test it(I am a terrible tester, I usually test a feature once or twice and that is it, I am kinda lazy about it, need to work on that).
With that said, I feel that I should stick to the code I have right now and see it through. But I took into account everything you said and I like the idea. I was thinking that about using the model/view approach in my next project but as soon as I release a stable version of my program with the current code, for the future updates I will begin refactoring everything to use the model/view approach and your guide here will be very useful. Thank you.
This is my first real-world application, up until now I was only on console based programs in codeblocks, I am still a student, only 2nd year and if you identified something I am might be doing wrong regarding my decision I stated above, or my mindset, please tell me.
-
@hbatalha Apart from your struggle with saving the data what worries me most is where the data is saved. Unless set otherwise on Windows, QSettings saves all the data to registry. I'd rather avoid that, you understand.
By the rule of thumb I prefer Qt to handle as much as possible on its own, which model/view approach allows to great extend.
Mind you, I don't say your approach will not work in the end.
I arrived to Qt world from Delphi/OpenPascal background so I am not the one to judge, did my share of less than optimal approaches. Good luck! -
@artwaw said in Is QSettings::setValue costly:
QSettings saves all the data to registry. I'd rather avoid that, you understand.
I set it to save to .ini files, I didn't try it but registry gave me a impression that it would be messy.
Mind you, I don't say your approach will not work in the end.
I know
Thank you for your insight