I'm working on a Gui-Module for Qt to plot realtime measurements like in an digital oscilloscope, based on Qwt. Everything works so far like it should, but maybe there are some features left to add ;-)
In the moment the data is stored column-wise in QVectors, together with one global timeReference QVector in one seperate QObject. So the data can be discarded row-wise to keep only Meusurement up to a certain past. All QVectors always have the same length. The complete data can then be row-wise time-correctly plotted in a QwtPlot.
I wanna encapsulate the data-storage more, to be more independent on working with the measurements. Therefore it would be nice to add a seperate List of time-coordinates for every measurement and put them both in a seperate QObject, which accepts and delievers the data. Then there would be 10 or 20 of such QObjects, one for every data-channel, which are seperately plotted by an overlying QObject on the QwtPlot.
The data can now be dynamically whatever -- how the data is stored, altered or discarded in between should not be visible to the outside.
My Question is: Is this smart? 20 or 30 QObjects containing each 10000 measurements, 10000 time-values, plus a seperate memory region of similar size (dynamically filled) where a subset ob the data is presented for plotting...? Is it sane to receive each measurement in its QObject as a signal, firing at around 1kHz? The signal/slot-part comes from the idea of making every OBject a QThread later, and implement real-time filtering, like low-pass or FFT on the data -- therefore, signal/slot connections are handy to controll the output in an multithreaded environment?
How could the data be stored efficiently inside my OBjects? I'm thinking about two QList, one for time and one for precious data. Then allocating two plain double-arrays on the fly for dynamic access, whose pointers together with the length are put in a struct and returned by an accessData(pastTime) method. The dynamic memory is filled with the timeVal/measurement combinations from "now" up to a certain point in the past, settable by a signal. Everything fragile secured by mutexes inside the QObject.
When discarding old values, the QList has to be searched from the beginning for the first value which is young enough to be kept, the ones residing before this index are thrown away. Is a QMap smarter because of its upperBound() function? I figure that the hidden overhead wouldn't be worth it.
How would one pro try to solve this problem nicely, efficiently or without any hassle? Special Qt-Features I should know about? Or are even free solutions out there? Anyhow, much text for such a basic question... Thanks for reading up to here ;-)
Thanks in advance
Marvin
edith: did some cleanup in argumentation after stijns comments.
photo_tom's answer pretty much sums it up: I'd stay away from QObjects for implementing the data handling and processing.
QObjects appear at first glance to be excellent way to handle storage issues for this type of data. I thought the same thing when I first starting using Qt. However, this is not what they are meant to be used for. There is a good writeup on what QObjects really are and do at http://www.informit.com/articles/article.aspx?p=667415.
If all you are going to do is store data in a class, as I read your question, then don't use QObject based classes. The overhead will seriously hurt your performance.
As to what Qt specific features would help you, there is nothing really specific to Qt that will help. What I found was the Qt's containers were much easier to use than standard template library or some of boost's specialized ones because at the time I didn't know stl well enough.
My best suggestion from a performance point of view is to minimize number new/deletes by writing a memory pool system or use Boost Pool for each new reading. And also minimize moving data at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With