Introduction
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.
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 |
Conclusion
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.
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?
ReplyDeleteWhen 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.
ReplyDeleteThings 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).