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.

bench.cc 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Benchmark Results:
  3. *
  4. * Big sequential insert:
  5. * L2 namespace: 0.177321
  6. * Absl flat map: 1.16507
  7. * Absl node map: 2.76126
  8. * unordered map: 1.63138
  9. * map: 2.16513
  10. * Big sequential lookup:
  11. * L2 namespace: 0.15393
  12. * Absl flat map: 2.2001
  13. * Absl node map: 2.5494
  14. * unordered map: 0.737267
  15. * map: 8.69381
  16. * Small rand insert:
  17. * L2 namespace: 0.103471
  18. * Absl flat map: 0.401839
  19. * Absl node map: 0.686433
  20. * unordered map: 0.422422
  21. * map: 0.31541
  22. * Small rand lookup:
  23. * L2 namespace: 0.19638
  24. * Absl flat map: 0.506841
  25. * Absl node map: 0.502917
  26. * unordered map: 0.738461
  27. * map: 0.471924
  28. */
  29. #include <unordered_map>
  30. #include <map>
  31. #include <absl/container/flat_hash_map.h>
  32. #include <absl/container/node_hash_map.h>
  33. #include <iostream>
  34. extern "C" {
  35. #include <lang2/vm/vm.h>
  36. #include <time.h>
  37. }
  38. double getTime() {
  39. struct timespec tv;
  40. clock_gettime(CLOCK_MONOTONIC, &tv);
  41. return tv.tv_sec + tv.tv_nsec / 1000000000.0;
  42. }
  43. struct L2Spec {
  44. static struct l2_vm_value alloc() {
  45. return {
  46. .flags = l2_value_type::L2_VAL_TYPE_NAMESPACE,
  47. .ns = nullptr,
  48. };
  49. }
  50. static void free(struct l2_vm_value &ns) {
  51. ::free(ns.ns);
  52. }
  53. static void insert(struct l2_vm_value &ns, l2_word key, l2_word val) {
  54. l2_vm_namespace_set(&ns, key, val);
  55. }
  56. static l2_word lookup(struct l2_vm_value &ns, l2_word key) {
  57. return l2_vm_namespace_get(NULL, &ns, key);
  58. }
  59. };
  60. template<typename T>
  61. struct CppSpec {
  62. static T alloc() {
  63. return {};
  64. }
  65. static void free(T &) {}
  66. static l2_word lookup(T &map, l2_word key) {
  67. auto it = map.find(key);
  68. if (it == map.end()) {
  69. return 0;
  70. } else {
  71. return it->second;
  72. }
  73. }
  74. static void insert(T &map, l2_word key, l2_word val) {
  75. map[key] = val;
  76. }
  77. };
  78. using UnorderedMapSpec = CppSpec<std::unordered_map<l2_word, l2_word>>;
  79. using MapSpec = CppSpec<std::map<l2_word, l2_word>>;
  80. using AbslFlatSpec = CppSpec<absl::flat_hash_map<l2_word, l2_word>>;
  81. using AbslNodeSpec = CppSpec<absl::node_hash_map<l2_word, l2_word>>;
  82. template<typename Spec>
  83. double testBigSeqInsert() {
  84. auto map = Spec::alloc();
  85. double start = getTime();
  86. for (int i = 1; i < 10000000; ++i) {
  87. Spec::insert(map, i, i * 10);
  88. }
  89. double t = getTime() - start;
  90. Spec::free(map);
  91. return t;
  92. }
  93. template<typename Spec>
  94. double testBigSeqLookup() {
  95. auto map = Spec::alloc();
  96. for (int i = 1; i < 1000000; ++i) {
  97. Spec::insert(map, i, i * 10);
  98. }
  99. volatile l2_word sum = 0;
  100. double start = getTime();
  101. for (int i = 0; i < 100; ++i) {
  102. for (int j = 1; j < 1000000; ++j) {
  103. sum += Spec::lookup(map, j);
  104. }
  105. }
  106. double t = getTime() - start;
  107. Spec::free(map);
  108. return t;
  109. }
  110. template<typename Spec>
  111. double testSmallRandInsert() {
  112. srand(0);
  113. l2_word rands[100];
  114. for (int i = 0; i < 100; ++i) {
  115. rands[i] = rand();
  116. }
  117. double start = getTime();
  118. for (int i = 0; i < 100000; ++i) {
  119. auto map = Spec::alloc();
  120. double start = getTime();
  121. for (int j = 0; j < 100; ++j) {
  122. Spec::insert(map, rands[j], j + 1);
  123. }
  124. Spec::free(map);
  125. }
  126. return getTime() - start;;
  127. }
  128. template<typename Spec>
  129. double testSmallRandLookup() {
  130. srand(0);
  131. l2_word rands[100];
  132. for (int i = 0; i < 100; ++i) {
  133. rands[i] = rand() % 100;
  134. }
  135. auto map = Spec::alloc();
  136. for (int j = 0; j < 100; ++j) {
  137. Spec::insert(map, rands[j], j + 1);
  138. }
  139. volatile l2_word sum = 0;
  140. double start = getTime();
  141. for (int j = 0; j < 100000000; ++j) {
  142. sum += Spec::lookup(map, rands[j % 100]);
  143. }
  144. double t = getTime() - start;
  145. Spec::free(map);
  146. return t;
  147. }
  148. int main() {
  149. std::cout << "Big sequential insert:\n";
  150. std::cout << "\tL2 namespace: " << testBigSeqInsert<L2Spec>() << '\n';
  151. std::cout << "\tAbsl flat map: " << testBigSeqInsert<AbslFlatSpec>() << '\n';
  152. std::cout << "\tAbsl node map: " << testBigSeqInsert<AbslNodeSpec>() << '\n';
  153. std::cout << "\tunordered map: " << testBigSeqInsert<UnorderedMapSpec>() << '\n';
  154. std::cout << "\tmap: " << testBigSeqInsert<MapSpec>() << '\n';
  155. std::cout << "Big sequential lookup:\n";
  156. std::cout << "\tL2 namespace: " << testBigSeqLookup<L2Spec>() << '\n';
  157. std::cout << "\tAbsl flat map: " << testBigSeqLookup<AbslFlatSpec>() << '\n';
  158. std::cout << "\tAbsl node map: " << testBigSeqLookup<AbslNodeSpec>() << '\n';
  159. std::cout << "\tunordered map: " << testBigSeqLookup<UnorderedMapSpec>() << '\n';
  160. std::cout << "\tmap: " << testBigSeqLookup<MapSpec>() << '\n';
  161. std::cout << "Small rand insert:\n";
  162. std::cout << "\tL2 namespace: " << testSmallRandInsert<L2Spec>() << '\n';
  163. std::cout << "\tAbsl flat map: " << testSmallRandInsert<AbslFlatSpec>() << '\n';
  164. std::cout << "\tAbsl node map: " << testSmallRandInsert<AbslNodeSpec>() << '\n';
  165. std::cout << "\tunordered map: " << testSmallRandInsert<UnorderedMapSpec>() << '\n';
  166. std::cout << "\tmap: " << testSmallRandInsert<MapSpec>() << '\n';
  167. std::cout << "Small rand lookup:\n";
  168. std::cout << "\tL2 namespace: " << testSmallRandLookup<L2Spec>() << '\n';
  169. std::cout << "\tAbsl flat map: " << testSmallRandLookup<AbslFlatSpec>() << '\n';
  170. std::cout << "\tAbsl node map: " << testSmallRandLookup<AbslNodeSpec>() << '\n';
  171. std::cout << "\tunordered map: " << testSmallRandLookup<UnorderedMapSpec>() << '\n';
  172. std::cout << "\tmap: " << testSmallRandLookup<MapSpec>() << '\n';
  173. }