benchmark.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include <gtest/gtest.h>
  2. #include <registry.hpp>
  3. #include <iostream>
  4. #include <cstddef>
  5. #include <chrono>
  6. #include <vector>
  7. struct Position {
  8. uint64_t x;
  9. uint64_t y;
  10. };
  11. struct Velocity {
  12. uint64_t x;
  13. uint64_t y;
  14. };
  15. template<std::size_t>
  16. struct Comp {};
  17. struct Timer final {
  18. Timer(): start{std::chrono::system_clock::now()} {}
  19. void elapsed() {
  20. auto now = std::chrono::system_clock::now();
  21. std::cout << std::chrono::duration<double>(now - start).count() << " seconds" << std::endl;
  22. }
  23. private:
  24. std::chrono::time_point<std::chrono::system_clock> start;
  25. };
  26. TEST(DefaultRegistry, Construct) {
  27. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  28. registry_type registry;
  29. std::cout << "Constructing 10000000 entities" << std::endl;
  30. Timer timer;
  31. for (uint64_t i = 0; i < 10000000L; i++) {
  32. registry.create();
  33. }
  34. timer.elapsed();
  35. registry.reset();
  36. }
  37. TEST(DefaultRegistry, Destroy) {
  38. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  39. registry_type registry;
  40. std::vector<registry_type::entity_type> entities{};
  41. std::cout << "Destroying 10000000 entities" << std::endl;
  42. for (uint64_t i = 0; i < 10000000L; i++) {
  43. entities.push_back(registry.create());
  44. }
  45. Timer timer;
  46. for (auto entity: entities) {
  47. registry.destroy(entity);
  48. }
  49. timer.elapsed();
  50. }
  51. TEST(DefaultRegistry, IterateCreateDeleteSingleComponent) {
  52. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  53. registry_type registry;
  54. std::cout << "Looping 10000 times creating and deleting a random number of entities" << std::endl;
  55. Timer timer;
  56. for(int i = 0; i < 10000; i++) {
  57. for(int j = 0; j < 10000; j++) {
  58. registry.create<Position>();
  59. }
  60. auto view = registry.view<Position>();
  61. for(auto entity: view) {
  62. if(rand() % 2 == 0) {
  63. registry.destroy(entity);
  64. }
  65. }
  66. }
  67. timer.elapsed();
  68. registry.reset();
  69. }
  70. TEST(DefaultRegistry, IterateSingleComponent10M) {
  71. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  72. registry_type registry;
  73. std::cout << "Iterating over 10000000 entities, one component" << std::endl;
  74. for (uint64_t i = 0; i < 10000000L; i++) {
  75. registry.create<Position>();
  76. }
  77. Timer timer;
  78. auto view = registry.view<Position>();
  79. for(auto entity: view) {
  80. auto &position = registry.get<Position>(entity);
  81. (void)position;
  82. }
  83. timer.elapsed();
  84. registry.reset();
  85. }
  86. TEST(DefaultRegistry, IterateTwoComponents10M) {
  87. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  88. registry_type registry;
  89. std::cout << "Iterating over 10000000 entities, two components" << std::endl;
  90. for (uint64_t i = 0; i < 10000000L; i++) {
  91. registry.create<Position, Velocity>();
  92. }
  93. Timer timer;
  94. auto view = registry.view<Position, Velocity>();
  95. for(auto entity: view) {
  96. auto &position = registry.get<Position>(entity);
  97. auto &velocity = registry.get<Velocity>(entity);
  98. (void)position;
  99. (void)velocity;
  100. }
  101. timer.elapsed();
  102. registry.reset();
  103. }
  104. TEST(DefaultRegistry, IterateTwoComponents10MHalf) {
  105. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  106. registry_type registry;
  107. std::cout << "Iterating over 10000000 entities, two components, half of the entities have all the components" << std::endl;
  108. for (uint64_t i = 0; i < 10000000L; i++) {
  109. auto entity = registry.create<Velocity>();
  110. if(i % 2) { registry.assign<Position>(entity); }
  111. }
  112. Timer timer;
  113. auto view = registry.view<Position, Velocity>();
  114. for(auto entity: view) {
  115. auto &position = registry.get<Position>(entity);
  116. auto &velocity = registry.get<Velocity>(entity);
  117. (void)position;
  118. (void)velocity;
  119. }
  120. timer.elapsed();
  121. registry.reset();
  122. }
  123. TEST(DefaultRegistry, IterateTwoComponents10MOne) {
  124. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  125. registry_type registry;
  126. std::cout << "Iterating over 10000000 entities, two components, only one entity has all the components" << std::endl;
  127. for (uint64_t i = 0; i < 10000000L; i++) {
  128. auto entity = registry.create<Velocity>();
  129. if(i == 5000000L) { registry.assign<Position>(entity); }
  130. }
  131. Timer timer;
  132. auto view = registry.view<Position, Velocity>();
  133. for(auto entity: view) {
  134. auto &position = registry.get<Position>(entity);
  135. auto &velocity = registry.get<Velocity>(entity);
  136. (void)position;
  137. (void)velocity;
  138. }
  139. timer.elapsed();
  140. registry.reset();
  141. }
  142. TEST(DefaultRegistry, IterateSingleComponent50M) {
  143. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  144. registry_type registry;
  145. std::cout << "Iterating over 50000000 entities, one component" << std::endl;
  146. for (uint64_t i = 0; i < 50000000L; i++) {
  147. registry.create<Position>();
  148. }
  149. Timer timer;
  150. auto view = registry.view<Position>();
  151. for(auto entity: view) {
  152. auto &position = registry.get<Position>(entity);
  153. (void)position;
  154. }
  155. timer.elapsed();
  156. registry.reset();
  157. }
  158. TEST(DefaultRegistry, IterateTwoComponents50M) {
  159. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  160. registry_type registry;
  161. std::cout << "Iterating over 50000000 entities, two components" << std::endl;
  162. for (uint64_t i = 0; i < 50000000L; i++) {
  163. registry.create<Position, Velocity>();
  164. }
  165. Timer timer;
  166. auto view = registry.view<Position, Velocity>();
  167. for(auto entity: view) {
  168. auto &position = registry.get<Position>(entity);
  169. auto &velocity = registry.get<Velocity>(entity);
  170. (void)position;
  171. (void)velocity;
  172. }
  173. timer.elapsed();
  174. registry.reset();
  175. }
  176. TEST(DefaultRegistry, IterateFiveComponents10M) {
  177. using registry_type = entt::DefaultRegistry<Position, Velocity, Comp<1>, Comp<2>, Comp<3>>;
  178. registry_type registry;
  179. std::cout << "Iterating over 10000000 entities, five components" << std::endl;
  180. for (uint64_t i = 0; i < 10000000L; i++) {
  181. registry.create<Position, Velocity, Comp<1>, Comp<2>, Comp<3>>();
  182. }
  183. Timer timer;
  184. auto view = registry.view<Position, Velocity, Comp<1>, Comp<2>, Comp<3>>();
  185. for(auto entity: view) {
  186. auto &position = registry.get<Position>(entity);
  187. auto &velocity = registry.get<Velocity>(entity);
  188. auto &comp1 = registry.get<Comp<1>>(entity);
  189. auto &comp2 = registry.get<Comp<2>>(entity);
  190. auto &comp3 = registry.get<Comp<3>>(entity);
  191. (void)position;
  192. (void)velocity;
  193. (void)comp1;
  194. (void)comp2;
  195. (void)comp3;
  196. }
  197. timer.elapsed();
  198. registry.reset();
  199. }
  200. TEST(DefaultRegistry, IterateTenComponents10M) {
  201. using registry_type = entt::DefaultRegistry<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>;
  202. registry_type registry;
  203. std::cout << "Iterating over 10000000 entities, ten components" << std::endl;
  204. for (uint64_t i = 0; i < 10000000L; i++) {
  205. registry.create<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  206. }
  207. Timer timer;
  208. auto view = registry.view<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  209. for(auto entity: view) {
  210. auto &position = registry.get<Position>(entity);
  211. auto &velocity = registry.get<Velocity>(entity);
  212. auto &comp1 = registry.get<Comp<1>>(entity);
  213. auto &comp2 = registry.get<Comp<2>>(entity);
  214. auto &comp3 = registry.get<Comp<3>>(entity);
  215. auto &comp4 = registry.get<Comp<4>>(entity);
  216. auto &comp5 = registry.get<Comp<5>>(entity);
  217. auto &comp6 = registry.get<Comp<6>>(entity);
  218. auto &comp7 = registry.get<Comp<7>>(entity);
  219. auto &comp8 = registry.get<Comp<8>>(entity);
  220. (void)position;
  221. (void)velocity;
  222. (void)comp1;
  223. (void)comp2;
  224. (void)comp3;
  225. (void)comp4;
  226. (void)comp5;
  227. (void)comp6;
  228. (void)comp7;
  229. (void)comp8;
  230. }
  231. timer.elapsed();
  232. registry.reset();
  233. }
  234. TEST(DefaultRegistry, IterateTenComponents10MHalf) {
  235. using registry_type = entt::DefaultRegistry<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>;
  236. registry_type registry;
  237. std::cout << "Iterating over 10000000 entities, ten components, half of the entities have all the components" << std::endl;
  238. for (uint64_t i = 0; i < 10000000L; i++) {
  239. auto entity = registry.create<Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  240. if(i % 2) { registry.assign<Position>(entity); }
  241. }
  242. Timer timer;
  243. auto view = registry.view<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  244. for(auto entity: view) {
  245. auto &position = registry.get<Position>(entity);
  246. auto &velocity = registry.get<Velocity>(entity);
  247. auto &comp1 = registry.get<Comp<1>>(entity);
  248. auto &comp2 = registry.get<Comp<2>>(entity);
  249. auto &comp3 = registry.get<Comp<3>>(entity);
  250. auto &comp4 = registry.get<Comp<4>>(entity);
  251. auto &comp5 = registry.get<Comp<5>>(entity);
  252. auto &comp6 = registry.get<Comp<6>>(entity);
  253. auto &comp7 = registry.get<Comp<7>>(entity);
  254. auto &comp8 = registry.get<Comp<8>>(entity);
  255. (void)position;
  256. (void)velocity;
  257. (void)comp1;
  258. (void)comp2;
  259. (void)comp3;
  260. (void)comp4;
  261. (void)comp5;
  262. (void)comp6;
  263. (void)comp7;
  264. (void)comp8;
  265. }
  266. timer.elapsed();
  267. registry.reset();
  268. }
  269. TEST(DefaultRegistry, IterateTenComponents10MOne) {
  270. using registry_type = entt::DefaultRegistry<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>;
  271. registry_type registry;
  272. std::cout << "Iterating over 10000000 entities, ten components, only one entity has all the components" << std::endl;
  273. for (uint64_t i = 0; i < 10000000L; i++) {
  274. auto entity = registry.create<Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  275. if(i == 5000000L) { registry.assign<Position>(entity); }
  276. }
  277. Timer timer;
  278. auto view = registry.view<Position, Velocity, Comp<1>, Comp<2>, Comp<3>, Comp<4>, Comp<5>, Comp<6>, Comp<7>, Comp<8>>();
  279. for(auto entity: view) {
  280. auto &position = registry.get<Position>(entity);
  281. auto &velocity = registry.get<Velocity>(entity);
  282. auto &comp1 = registry.get<Comp<1>>(entity);
  283. auto &comp2 = registry.get<Comp<2>>(entity);
  284. auto &comp3 = registry.get<Comp<3>>(entity);
  285. auto &comp4 = registry.get<Comp<4>>(entity);
  286. auto &comp5 = registry.get<Comp<5>>(entity);
  287. auto &comp6 = registry.get<Comp<6>>(entity);
  288. auto &comp7 = registry.get<Comp<7>>(entity);
  289. auto &comp8 = registry.get<Comp<8>>(entity);
  290. (void)position;
  291. (void)velocity;
  292. (void)comp1;
  293. (void)comp2;
  294. (void)comp3;
  295. (void)comp4;
  296. (void)comp5;
  297. (void)comp6;
  298. (void)comp7;
  299. (void)comp8;
  300. }
  301. timer.elapsed();
  302. registry.reset();
  303. }
  304. TEST(DefaultRegistry, SortSingle) {
  305. using registry_type = entt::DefaultRegistry<Position>;
  306. registry_type registry;
  307. std::vector<registry_type::entity_type> entities{};
  308. std::cout << "Sort 10000000 entities" << std::endl;
  309. for (uint64_t i = 0; i < 10000000L; i++) {
  310. auto entity = registry.create();
  311. entities.push_back(entity);
  312. registry.assign<Position>(entity, i, i);
  313. }
  314. Timer timer;
  315. registry.sort<Position>([](const auto &lhs, const auto &rhs) {
  316. return lhs.x < rhs.x && lhs.y < rhs.y;
  317. });
  318. timer.elapsed();
  319. }
  320. TEST(DefaultRegistry, SortMulti) {
  321. using registry_type = entt::DefaultRegistry<Position, Velocity>;
  322. registry_type registry;
  323. std::vector<registry_type::entity_type> entities{};
  324. std::cout << "Sort 10000000 entities" << std::endl;
  325. for (uint64_t i = 0; i < 10000000L; i++) {
  326. auto entity = registry.create();
  327. entities.push_back(entity);
  328. registry.assign<Position>(entity, i, i);
  329. registry.assign<Velocity>(entity, i, i);
  330. }
  331. registry.sort<Position>([](const auto &lhs, const auto &rhs) {
  332. return lhs.x < rhs.x && lhs.y < rhs.y;
  333. });
  334. Timer timer;
  335. registry.sort<Velocity, Position>();
  336. timer.elapsed();
  337. }