C++ Delegate Libraries Performance Benchmark

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • C++ Delegate Libraries Performance Benchmark

      [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:
      • 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

      1. Visual Studio 2013
      2. ###################################### parameter less
      3. [member function]
      4. raw : 0ms
      5. std::function : 212ms
      6. ssuv::FastFunc : 135ms
      7. FastDelegate : 135ms
      8. FastDelegate C++11 : 135ms
      9. SR Delegate C++11 : 158ms
      10. [static class function]
      11. raw : 0ms
      12. std::function : 203ms
      13. ssuv::FastFunc : 180ms
      14. FastDelegate : 180ms
      15. FastDelegate C++11 : 180ms
      16. SR Delegate C++11 : 158ms
      17. [static global function]
      18. raw : 0ms
      19. std::function : 204ms
      20. ssuv::FastFunc : 186ms
      21. FastDelegate : 180ms
      22. FastDelegate C++11 : 180ms
      23. SR Delegate C++11 : 158ms
      24. ###################################### EventSPtr as parameter
      25. [member function]
      26. raw : 2239ms
      27. std::function : 5219ms
      28. ssuv::FastFunc : 2864ms
      29. FastDelegate : 4284ms
      30. FastDelegate C++11 : 4257ms
      31. SR Delegate C++11 : 2940ms
      32. [static class function]
      33. raw : 2284ms
      34. std::function : 4018ms
      35. ssuv::FastFunc : 3392ms
      36. FastDelegate : 5765ms
      37. FastDelegate C++11 : 5705ms
      38. SR Delegate C++11 : 2950ms
      39. [static global function]
      40. raw : 2646ms
      41. std::function : 4358ms
      42. ssuv::FastFunc : 3568ms
      43. FastDelegate : 5735ms
      44. FastDelegate C++11 : 5712ms
      45. SR Delegate C++11 : 2941ms
      46. ######################################
      47. raw equality test : 1
      48. SR Delegate C++11 equality test : 1
      49. SR Delegate C++11 inequality test : 0
      50. SR Delegate C++11 equality test : 1
      51. FastFunc C++11 equality test : 1
      52. FastFunc C++11 inequality test : 0
      53. FastDelegate C++11 equality test : 1
      54. FastDelegate C++11 inequality test : 0
      55. FastDelegate C++11 equality test : 1
      Display All

      Source Code

      1. Qt5.3 MinGW4.8.1?
      2. ###################################### parameter less
      3. [member function]
      4. raw : 0ms
      5. std::function : 368ms
      6. ssuv::FastFunc : 0ms
      7. FastDelegate : 0ms
      8. FastDelegate C++11 : 0ms
      9. SR Delegate C++11 : 0ms
      10. [static class function]
      11. raw : 0ms
      12. std::function : 270ms
      13. ssuv::FastFunc : 226ms
      14. FastDelegate : 225ms
      15. FastDelegate C++11 : 248ms
      16. SR Delegate C++11 : 0ms
      17. [static global function]
      18. raw : 0ms
      19. std::function : 270ms
      20. ssuv::FastFunc : 248ms
      21. FastDelegate : 230ms
      22. FastDelegate C++11 : 226ms
      23. SR Delegate C++11 : 0ms
      24. ###################################### EventSPtr as parameter
      25. [member function]
      26. raw : 2080ms
      27. std::function : 2757ms
      28. ssuv::FastFunc : 2266ms
      29. FastDelegate : 3279ms
      30. FastDelegate C++11 : 3283ms
      31. SR Delegate C++11 : 2093ms
      32. [static class function]
      33. raw : 2093ms
      34. std::function : 2679ms
      35. ssuv::FastFunc : 2409ms
      36. FastDelegate : 4528ms
      37. FastDelegate C++11 : 4515ms
      38. SR Delegate C++11 : 2099ms
      39. [static global function]
      40. raw : 2262ms
      41. std::function : 2698ms
      42. ssuv::FastFunc : 2407ms
      43. FastDelegate : 4482ms
      44. FastDelegate C++11 : 4516ms
      45. SR Delegate C++11 : 2260ms
      46. ######################################
      47. raw equality test : 1
      48. SR Delegate C++11 equality test : 1
      49. SR Delegate C++11 inequality test : 0
      50. SR Delegate C++11 equality test : 1
      51. FastFunc C++11 equality test : 1
      52. FastFunc C++11 inequality test : 0
      53. FastDelegate C++11 equality test : 1
      54. FastDelegate C++11 inequality test : 0
      55. FastDelegate C++11 equality test : 1
      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.
      BenH

      The post was edited 3 times, last by boxy ().

    • Originally posted by DieselMaxPower
      I'll probably keep std::function just because it's easier to find support and doesn't introduce a library dependency, but this is good info!


      I would have agreed with you several months ago, but not any more.

      The only dependency that you would introduce to your project by using most of these libraries is only 1 header files. From an ease of use and performance stand point, std::function is at the bottom of the list. What kind of support do you need if they work out of the box? The C++11 versions of these libraries are only several hundred lines of code (ignoring my VC workarounds), I would rather maintain that myself than waiting for STL maintainers to fix any bugs. Especially if it was a Visual Studio one.

      I will be replacing std::function with either ssvu::Fastfunc or SRDelegate in my framework. Last time I checked, the C++11 implementation of SRDelegate is still actively being maintained (or at least the chunk that it belongs to is anyway).

      EDIT: remove double quote.
      BenH

      The post was edited 1 time, last by boxy ().

    • I don't disagree with any of that. But, if I stick to the STL I can ask questions on stack overflow and get more google results. The community and resources for any of the fast delegate implementations are certainly going to be smaller.

      I wouldn't hesitate adopting these in production quality codes, but I want to keep this game demo as simple as possible.