You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.2 KiB

2 months ago
  1. #include <map>
  2. #include <unordered_map>
  3. #include <string>
  4. #include <iostream>
  5. #include <chrono>
  6. #include <vector>
  7. #include <sparsepp/spp.h>
  8. #include <sstream>
  9. namespace patch
  10. {
  11. template <typename T> std::string to_string(const T& n)
  12. {
  13. std::ostringstream stm;
  14. stm << n;
  15. return stm.str();
  16. }
  17. }
  18. #if defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  19. #warning "problem: we expect spp will detect we have rvalue support"
  20. #endif
  21. template <typename T>
  22. using milliseconds = std::chrono::duration<T, std::milli>;
  23. class custom_type
  24. {
  25. std::string one = "one";
  26. std::string two = "two";
  27. std::uint32_t three = 3;
  28. std::uint64_t four = 4;
  29. std::uint64_t five = 5;
  30. public:
  31. custom_type() = default;
  32. // Make object movable and non-copyable
  33. custom_type(custom_type &&) = default;
  34. custom_type& operator=(custom_type &&) = default;
  35. // should be automatically deleted per http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014
  36. //custom_type(custom_type const&) = delete;
  37. //custom_type& operator=(custom_type const&) = delete;
  38. };
  39. void test(std::size_t iterations, std::size_t container_size)
  40. {
  41. std::clog << "bench: iterations: " << iterations << " / container_size: " << container_size << "\n";
  42. {
  43. std::size_t count = 0;
  44. auto t1 = std::chrono::high_resolution_clock::now();
  45. for (std::size_t i=0; i<iterations; ++i)
  46. {
  47. std::unordered_map<std::string,custom_type> m;
  48. m.reserve(container_size);
  49. for (std::size_t j=0; j<container_size; ++j)
  50. m.emplace(patch::to_string(j),custom_type());
  51. count += m.size();
  52. }
  53. auto t2 = std::chrono::high_resolution_clock::now();
  54. auto elapsed = milliseconds<double>(t2 - t1).count();
  55. if (count != iterations*container_size)
  56. std::clog << " invalid count: " << count << "\n";
  57. std::clog << " std::unordered_map: " << std::fixed << int(elapsed) << " ms\n";
  58. }
  59. {
  60. std::size_t count = 0;
  61. auto t1 = std::chrono::high_resolution_clock::now();
  62. for (std::size_t i=0; i<iterations; ++i)
  63. {
  64. std::map<std::string,custom_type> m;
  65. for (std::size_t j=0; j<container_size; ++j)
  66. m.emplace(patch::to_string(j),custom_type());
  67. count += m.size();
  68. }
  69. auto t2 = std::chrono::high_resolution_clock::now();
  70. auto elapsed = milliseconds<double>(t2 - t1).count();
  71. if (count != iterations*container_size)
  72. std::clog << " invalid count: " << count << "\n";
  73. std::clog << " std::map: " << std::fixed << int(elapsed) << " ms\n";
  74. }
  75. {
  76. std::size_t count = 0;
  77. auto t1 = std::chrono::high_resolution_clock::now();
  78. for (std::size_t i=0; i<iterations; ++i)
  79. {
  80. std::vector<std::pair<std::string,custom_type>> m;
  81. m.reserve(container_size);
  82. for (std::size_t j=0; j<container_size; ++j)
  83. m.emplace_back(patch::to_string(j),custom_type());
  84. count += m.size();
  85. }
  86. auto t2 = std::chrono::high_resolution_clock::now();
  87. auto elapsed = milliseconds<double>(t2 - t1).count();
  88. if (count != iterations*container_size)
  89. std::clog << " invalid count: " << count << "\n";
  90. std::clog << " std::vector<std::pair>: " << std::fixed << int(elapsed) << " ms\n";
  91. }
  92. {
  93. std::size_t count = 0;
  94. auto t1 = std::chrono::high_resolution_clock::now();
  95. for (std::size_t i=0; i<iterations; ++i)
  96. {
  97. spp::sparse_hash_map<std::string,custom_type> m;
  98. m.reserve(container_size);
  99. for (std::size_t j=0; j<container_size; ++j)
  100. m.emplace(patch::to_string(j),custom_type());
  101. count += m.size();
  102. }
  103. auto t2 = std::chrono::high_resolution_clock::now();
  104. auto elapsed = milliseconds<double>(t2 - t1).count();
  105. if (count != iterations*container_size)
  106. std::clog << " invalid count: " << count << "\n";
  107. std::clog << " spp::sparse_hash_map: " << std::fixed << int(elapsed) << " ms\n";
  108. }
  109. }
  110. int main()
  111. {
  112. std::size_t iterations = 100000;
  113. test(iterations,1);
  114. test(iterations,10);
  115. test(iterations,50);
  116. }