Does it emit copies of its arguments?

I want to know about emit . Is data duplicating?

If I need to pass an array of 1 MB of bytes through it, how many copies of this byte array will exist in memory?

+4
source share
3 answers

It depends on how your signals are connected to the slots.

If you use the default connection, Qt::DirectConnection , and two QObject are in the same thread, then the parameters are processed as if you called the function in the usual way according to how you defined the parameters (pass-by reference or skipped value).

If you connect using Qt::QueuedConnection or you are connected between threads, the argument arguments are copied and passed to a special QEvent and added to the event queue of the receiving thread. This will then be handled by the receiving stream when it gets a chance.

+4
source

It depends on how the connections are created and how you pass the parameters.

  • Scroll by value (i.e. signals: void foo(Bar); )

    • A normal C ++ function call will generate one copy (copy Bar from the caller to the callee).
    • A call with a direct connection / slot generates two copies: the emission function called by moc is called (one copy, the same as above), the parameter β€œpackets” and calls to QMetaObject::activate , which ends by calling your qt_static_metacall class, which calls the slot ( like a regular function call) that carries a second copy.
    • A call / slot call associated with a queue generates three copies. In the calling context, the emit function calls itself, as described above, and a copy of the parameter in the event. In the context of the receiver, the same qt_static_metacall slot call is used.
  • Pass a constant (i.e. signals: void foo(Bar const&); )

    • Normal C ++ function call: no copy.
    • Direct call / slot call: no copy.
    • Auxiliary call of the signal / slot in the queue: one copy, one in the event object described above.
  • Pass a link (not const) (i.e. signals: void foo(Bar&); )

    • Normal C ++ function call: no copy.
    • Direct call / slot call: no copy.
    • Auxiliary Call / Slot Associated with Queue: Impossible (AFAIK).

A copy of the event is mentioned in the documents :

If there are connections in the queue, the parameters must be of types that are known to the Qt meta-object system, because Qt needs to copy the arguments to store them in the event behind the scenes.

Now the real question is: does it matter?

If you use the Qt container class that uses implicit exchange , in normal cases it does not matter - the payload won't be copied if necessary. Therefore, copies should not have a significant impact on overall performance.

If you do not use implicit exchange, then passing massive objects by value is probably not the right choice, but calling a slot will be more expensive than a regular function call. Direct-connected slots and pass-by-const-ref will behave just like regular function calls, but queue slots will be more expensive.

+3
source

All Qt containers implement the copy on write pattern. Therefore, when you pass a container by value, nothing is copied until you use the none-const method of that container.

So bottom line: safe (will not double memory consumption) to pass large qt containers through signals and slots.

0
source

Source: https://habr.com/ru/post/1501454/


All Articles