PDA

View Full Version : Efficiency of the signal and slot mechanism



Momergil
23rd April 2014, 15:13
Hello!

For a moment I'm questioning the efficiency of the signals and slot mechanism available in Qt/QObject for a particular use in embedded systems where processing is limited as well as memory.

In a particular situation, a given hardware collects data from somewhere and passes it to a Qt GUI application via C implemented socket. A QThread-based class in the Qt application reads the data from the socket in a synchronous way and when the data arrives, it should process it, sending to the lots of graphs and others in widgets.

The question is: how to most efficiently do this connection between the data received and processed and the graphs?

The first option I imagined was passing by signals and slots this 1º way: a processData(QByteArray&) method in the processing thread would create the small blocks of data as they arrive and emit a signal after processed, one for each kind of data pack received. When the user, then, opens a specific graph/widget, a connect(...) is performed and the data begins to appear in the GUI. When the widget is closed, a disconnect(...) is called.

The problem of this method is that it would imply lots of calling to signals with no slots connected to them, that is, useless signal emitting, and AFAIK, the whole signal process is called by Qt even if there is not slot connected to them.

A second option I thought was that the signals emitting would be blocked by boolean flags that would be set to "true" each time a widget is open (and a connect(...) is made). This way the emitting of unconnected signals would be stopped and the problem mentioned above would cease. The problem is that in order for this system to be implemented, lots of new signals and slots would be created, one for each new flag! This would make the code far more complicated and less elegant, although there would probably be still an advantage in processing.


So I'ld like to know if there is another way of doing this which is as simpler as it can be, such as in the first way (only a connect(...) is called), but with a good improve in processing consumption as well (such as in the second solution). Of course, if someone tells me that a emit signal(...) is not executed if Qt knows that no slot is connected to it, than all doubts are ceased and I'll use the first solution.


Thanks,

Momergil

d_stranz
23rd April 2014, 18:41
useless signal emitting

QObject has a "isSignalConnected()" protected method which your data acquisition class could use to determine whether to emit a signal or not. I have not investigated the Qt internals to determine if Qt itself uses this method to decide whether to emit a signal or not.

The whole idea behind the signal / slot mechanism is abstraction. A receiver does not need to know anything about a sender other than that it emits a signal with a given signature. Likewise, a sender does not need to know anything about the receiver (and potentially, might not even care if there are receivers listening for a signal). This abstraction means that you can implement senders and receivers in any way you like so long as the signal / slot "contract" is homored.

This is probably not as efficient as direct method calls, but the downside of that is that all parts of your system must know details about each other, and replacing one component with a substitute might involve recompiling a lot of code. With the signals and slots published in base classes, any derived class can be used and likely won't involve any more than recompilation of just a few modules, if any, and a relink.

Momergil
23rd April 2014, 20:28
Thanks d_stranz for the reply.

About the method, "This function was introduced in QtCore 5.0.", while I'm considering Qt 4.8 :T

Regarding recompilation, that's not a problem. The whole problem is processing and memory consumption. I'm also aware that the signals and slot mechanism is not as efficient as direct method call, but that is, in fact, not the biggest of my concern, but actually the useless processing arising from emitting signals unnecessarily (if I use the first of the mentioned methods above). Notice that the systems will emit lots of data in high frequency, so lots of useless signals being emitted is really bad. Using direct method call, by the other hand, probably wouldn't get around the second solution with its problems, as well as make the app far more complicated that the already problematic second solution mentioned above \o/

Now re-reading the QObject Qt Assistant files, I found the QObject::receivers protected method, which may give a help in finding a better solution for this problem than the two solutions mentioned above (a more elegant way of doing the second, that is). But I'm still curious about other, maybe better solutions. :)