Tuesday, August 6, 2013

Signals3 Source Code and Performance Testing Update


Since my last post on a fast thread-safe Signals/Slots implementation I've had to do a major re-write. The problem was that I had merged "slots" with nodes. This made implementing "self-disconnecting" slots near impossible (or at least, very inefficient). I also had structured my code quite poorly so managing includes was a nightmare.

Getting the Code

The code is currently being hosted by GitHub. It is released under the Boost Software License, v1.0. For those who pay attention to the commit dates, they'll realize that the repo is actually newer than some of my posts on the subject (yes, I wrote those posts in advance). At this time I have implemented nearly all features offered by Boost Signals2, though there may be bugs in the code. See the repository for up-to-date and more specific information on the state of the project .

Performance Tests

These results were tested using this revision. I've listed performance stats for using the library in both thread-safe and thread-unsafe mode. As always, I'm building with Mingw-w64* for x64 Windows 7 (gcc 4.8.1), running on a laptop with an Intel i5-m430.

note*: Qt Signals/Slots was built using VS2012 update 3 because I don't want to re-build the Qt library with Mingw-w64.
Table 1. Emit Testing
Test Case No Slots (ns) 1 Slot (ns) 2 Slots (ns) 4 Slots (ns) 8 Slots (ns) 16 Slots (ns) 32 Slots (ns) 64 Slots (ns) static overhead (ns) dynamic overhead (ns/slot)
std::function calls 0 3.5 7.5 15 29 60 116 232 0 3.6
Qt Signals/Slots 14 75 115 177 312 581 1123 2202 40 33.8
Boost Signals2 75 137 183 253 398 705 1280 2500 75 37
Signals3 Thread-safe mode 17 52 86 153 290 559 1098 2158 17 33
Signals3 Thread-unsafe mode 17 44 69 123 227 435 842 1650 17 25


Implementing the automatic disconnect feature has slightly reduced the performance of the library, but it is still quite fast compared to other thread-safe implementations. I don't expect emit performance to change as I add on the last few missing features because none of them require modifying the emit algorithm. The implementation has reached at least a "playable" state, but is still far from being production-ready due to the lack of extensive testing. Comments and suggestions for improvement are definitely welcome.


  1. I love the work you have been doing on this. I would like to use it, but I am trying to not use boost. Do you think it is possible to remove the boost dependencies? And if so, could you point me in the right direction of how to remove the boost dependencies?

  2. When I was writing this library there wasn't any compiler+standard library package available to me which had the required C++11 features. I've tried to carefully write the library such that these dependencies will go away as the standard library supports them. The main notable exception is Boost::Optional, which is a part of the default collector class. There is a proposal as a technical specifications to have std::optional, but I haven't looked into the details of how compatible this is with boost::optional. I also originally wanted to back-port this to C++03, but I just don't have the time to work on this more.

    Things that I remember missing from compilers/standard libraries:

    cstdlib 4.8.1 (gcc) doesn't have "atomic" shared_ptr.

    On Windows, gcc 4.8.1 (mingw-w64) didn't have any thread-related libraries.

    VS2012 didn't support variadic templates. I don't know what library features were missing from VS2012.

    There is a compiler_support.hpp file which will automatically use standard features if they are available, which depends on Boost.Config. You can hard-code this to using standard C++11 features if you want to get rid of the Boost.Config dependency, or even direct Signals3 to use your own implementation (I tried to only assume C++11 standard-compliant usage of the Boost libraries).