[To the Mods: I'm unsure whether I have posted under the right forum section. Please move this if I am. ]
I know there are quite a few that are entertained by the book authors' delegate library choice and it's possible alternatives. I myself have asked the question of the practicality in an alternative implementation where std::function + some sort of identifier are used instead of Don Clougston's FastDelegate library (in this post). I've since implemented said approach in my framework and realized that at the end of the day, a comparable delegate object is much more elegant than std::function which does not support comparison between 2 std::function's.
Not being able to compare delegates is a huge pain in the butt to register and de-register static class function and free functions, but std::function's lambda support is very desirable. I ended searching for other modern delegate library alternatives that are high performance, is comparable and provide lambda support, and was able to find the following that supports some if not all of the requirements:
I've created a performance benchmark comparing these new libraries plus std::function, the original FastDelegate and raw function calls on GitHub (link ). Both a QtCreator project and a Visual Studio 2013 solution are provided. Some workarounds are added for the C++11 versions of the libraries due to Visual Studio's poor C++11 conformance.
The benchmark creates delegates for member functions, static class functions and static free functions and timed their operator() performance over 100 million calls. Here are the results for the MinGW(4.8.1?) and VC++12:
Display All
Display All
It is quite amusing to see that for this benchmark, the original FastDelegate does not perform any better than std::function (it is in fact worst in some scenarios). I am also surprised that the VC build does not perform better than the MinGW build.
All source is available on GitHub (link) including links to library source.
UPDATE(2014/07/12): The libraries are now also available in this repo (link), I've also updated the benchmark with fixes and updated libraries.
I know there are quite a few that are entertained by the book authors' delegate library choice and it's possible alternatives. I myself have asked the question of the practicality in an alternative implementation where std::function + some sort of identifier are used instead of Don Clougston's FastDelegate library (in this post). I've since implemented said approach in my framework and realized that at the end of the day, a comparable delegate object is much more elegant than std::function which does not support comparison between 2 std::function's.
Not being able to compare delegates is a huge pain in the butt to register and de-register static class function and free functions, but std::function's lambda support is very desirable. I ended searching for other modern delegate library alternatives that are high performance, is comparable and provide lambda support, and was able to find the following that supports some if not all of the requirements:
- FastDelegate C++11 (a C++11 re-implementation of FastDelegate)
- ssuv::FastFunc (a different C++11 adaptation of FastDelegate)
- SRDelegate C++11 (a C++11 re-implementation of SRDelegate)
I've created a performance benchmark comparing these new libraries plus std::function, the original FastDelegate and raw function calls on GitHub (link ). Both a QtCreator project and a Visual Studio 2013 solution are provided. Some workarounds are added for the C++11 versions of the libraries due to Visual Studio's poor C++11 conformance.
The benchmark creates delegates for member functions, static class functions and static free functions and timed their operator() performance over 100 million calls. Here are the results for the MinGW(4.8.1?) and VC++12:
Source Code
- Visual Studio 2013
- ###################################### parameter less
- [member function]
- raw : 0ms
- std::function : 212ms
- ssuv::FastFunc : 135ms
- FastDelegate : 135ms
- FastDelegate C++11 : 135ms
- SR Delegate C++11 : 158ms
- [static class function]
- raw : 0ms
- std::function : 203ms
- ssuv::FastFunc : 180ms
- FastDelegate : 180ms
- FastDelegate C++11 : 180ms
- SR Delegate C++11 : 158ms
- [static global function]
- raw : 0ms
- std::function : 204ms
- ssuv::FastFunc : 186ms
- FastDelegate : 180ms
- FastDelegate C++11 : 180ms
- SR Delegate C++11 : 158ms
- ###################################### EventSPtr as parameter
- [member function]
- raw : 2239ms
- std::function : 5219ms
- ssuv::FastFunc : 2864ms
- FastDelegate : 4284ms
- FastDelegate C++11 : 4257ms
- SR Delegate C++11 : 2940ms
- [static class function]
- raw : 2284ms
- std::function : 4018ms
- ssuv::FastFunc : 3392ms
- FastDelegate : 5765ms
- FastDelegate C++11 : 5705ms
- SR Delegate C++11 : 2950ms
- [static global function]
- raw : 2646ms
- std::function : 4358ms
- ssuv::FastFunc : 3568ms
- FastDelegate : 5735ms
- FastDelegate C++11 : 5712ms
- SR Delegate C++11 : 2941ms
- ######################################
- raw equality test : 1
- SR Delegate C++11 equality test : 1
- SR Delegate C++11 inequality test : 0
- SR Delegate C++11 equality test : 1
- FastFunc C++11 equality test : 1
- FastFunc C++11 inequality test : 0
- FastDelegate C++11 equality test : 1
- FastDelegate C++11 inequality test : 0
- FastDelegate C++11 equality test : 1
Source Code
- Qt5.3 MinGW4.8.1?
- ###################################### parameter less
- [member function]
- raw : 0ms
- std::function : 368ms
- ssuv::FastFunc : 0ms
- FastDelegate : 0ms
- FastDelegate C++11 : 0ms
- SR Delegate C++11 : 0ms
- [static class function]
- raw : 0ms
- std::function : 270ms
- ssuv::FastFunc : 226ms
- FastDelegate : 225ms
- FastDelegate C++11 : 248ms
- SR Delegate C++11 : 0ms
- [static global function]
- raw : 0ms
- std::function : 270ms
- ssuv::FastFunc : 248ms
- FastDelegate : 230ms
- FastDelegate C++11 : 226ms
- SR Delegate C++11 : 0ms
- ###################################### EventSPtr as parameter
- [member function]
- raw : 2080ms
- std::function : 2757ms
- ssuv::FastFunc : 2266ms
- FastDelegate : 3279ms
- FastDelegate C++11 : 3283ms
- SR Delegate C++11 : 2093ms
- [static class function]
- raw : 2093ms
- std::function : 2679ms
- ssuv::FastFunc : 2409ms
- FastDelegate : 4528ms
- FastDelegate C++11 : 4515ms
- SR Delegate C++11 : 2099ms
- [static global function]
- raw : 2262ms
- std::function : 2698ms
- ssuv::FastFunc : 2407ms
- FastDelegate : 4482ms
- FastDelegate C++11 : 4516ms
- SR Delegate C++11 : 2260ms
- ######################################
- raw equality test : 1
- SR Delegate C++11 equality test : 1
- SR Delegate C++11 inequality test : 0
- SR Delegate C++11 equality test : 1
- FastFunc C++11 equality test : 1
- FastFunc C++11 inequality test : 0
- FastDelegate C++11 equality test : 1
- FastDelegate C++11 inequality test : 0
- FastDelegate C++11 equality test : 1
It is quite amusing to see that for this benchmark, the original FastDelegate does not perform any better than std::function (it is in fact worst in some scenarios). I am also surprised that the VC build does not perform better than the MinGW build.
All source is available on GitHub (link) including links to library source.
UPDATE(2014/07/12): The libraries are now also available in this repo (link), I've also updated the benchmark with fixes and updated libraries.
BenH
The post was edited 3 times, last by boxy ().