Open sq-gilles opened 1 year ago
Hi,
First of all thanks a lot for a very clever repro case, for linking to the matching Qt docs, and for proposing a patch as well :+1:
This is something I was aware of, and silently hoped nobody would need them to be processed in order :sweat_smile: The only concern I have is lookup performance -- asymptotically at least, and considering a good-enough hash function, the hashmap would have a O(1) lookup complexity, while the tree-based map O(log n). But the constant factors in the hashmap case are quite high so it's possible the tree-based map still wins in most cases.
There's a benchmark among the test files, built as InterconnectBenchmark
. Could you run it before and after to compare the perf? If the difference is acceptable, I'm happy to merge this as-is, if not then the solution would need to be something like a std::unordered_map<SignalData, std::vector<ConnectionData>>
instead. That could guarantee order as well and even be a bit faster than the original, as each connection wouldn't be a separate loose allocation. The only downside would be potentially slower connection removal.
Thanks!
Hi,
Using the signal/slot library of Corrade, it appears that when one attaches many slots to same signal, the slots are not called in any particular order. In particular, there are not called in the record order.
We can easily see that by tweaking the Corrade/Interconnect/Test/LibraryTest.cpp
Controlling the slot invocation order is mandatory when we want to manage events layer by layer (e.g. when managing io events in a scene graph). For example Qt (that seems to have inspired this api) ensures this behavior https://doc.qt.io/qt-6/signalsandslots.html#signals
This is due to the usage of std::unordered_multimap in src/Corrade/Interconnect/Emitter.h:510. In fact, there is no guarantee on the order for "key-value pairs whose keys compare equivalent".
A very simple fix would be to replace the unordered_multimap by a multimap. Indeed, multimap ensures the order of equivalent keys is the same as their insertion order (https://en.cppreference.com/w/cpp/container/multimap)