fork(2) download
  1. #include <iostream>
  2. #include <chrono>
  3. #include <map>
  4. #include <string>
  5. #include <random>
  6. #include <algorithm>
  7. #include <unordered_set>
  8. #include <set>
  9.  
  10. template <class T, class ValueType>
  11. class StrongType
  12. {
  13. public:
  14. inline explicit operator ValueType() const { return _value;}
  15. inline bool operator == (const StrongType &other) const
  16. {
  17. return _value == other._value;
  18. }
  19. inline bool operator != (const StrongType &other) const
  20. {
  21. return _value != other._value;
  22. }
  23. inline bool operator < (const StrongType &other) const
  24. {
  25. return _value < other._value;;
  26. }
  27. inline bool operator > (const StrongType &other) const
  28. {
  29. return _value > other._value;
  30. }
  31. inline bool operator <= (const StrongType &other) const
  32. {
  33. return _value <= other._value;
  34. }
  35. inline bool operator >= (const StrongType &other) const
  36. {
  37. return _value >= other._value;
  38. }
  39.  
  40. protected:
  41. explicit StrongType(ValueType value):_value(value) {}
  42.  
  43. private:
  44. ValueType _value;
  45. };
  46.  
  47. template <class T, class ValueType = int>
  48. class StringCache
  49. {
  50. public:
  51. static_assert(std::is_integral<ValueType>::value, "not integral type");
  52.  
  53. class Type: public StrongType<T,ValueType>
  54. {
  55. friend class StringCache;
  56. public:
  57. explicit operator bool() const { return static_cast<ValueType>(*this)!=0; }
  58.  
  59. private:
  60. explicit Type(ValueType value):StrongType<T,ValueType>(value){}
  61. };
  62.  
  63. static Type get(const std::string &value)
  64. {
  65. return Type(_values.insert(std::make_pair(value, _values.size() + 1)).first->second);
  66. }
  67.  
  68. static Type find(const std::string &value)
  69. {
  70. std::map<std::string,int>::const_iterator it =_values.find(value);
  71. if(it == _values.end())
  72. return Type(0);
  73. else
  74. return Type(it->second);
  75. }
  76.  
  77. static const std::string& to_string(const Type &type)
  78. {
  79. static const std::string empty;
  80. if(static_cast<ValueType>(type)>=_values.size())
  81. return empty;
  82. for(const auto &it:_values)
  83. if(it.second == static_cast<ValueType>(type))
  84. return it.first;
  85. return empty;
  86. }
  87.  
  88. private:
  89. static std::map<std::string,int> _values;
  90. };
  91.  
  92. template <class T, class ValueType>
  93. std::map<std::string,int> StringCache<T,ValueType>::_values;
  94.  
  95.  
  96.  
  97. class EventType:public StringCache<EventType>{};
  98.  
  99. class Script
  100. {
  101. public:
  102. Script(int val):_value(val)
  103. {
  104.  
  105. }
  106. int execute() const
  107. {
  108. return _value;
  109. }
  110. private:
  111. int _value;
  112. };
  113.  
  114. class Object
  115. {
  116. public:
  117. int execute(const std::string &id) const
  118. {
  119. auto it = _events.find(id);
  120. if(it!=_events.end())
  121. {
  122. return it->second.execute();
  123. }
  124. return 0;
  125. }
  126. void addevent(const std::string &event, const Script &script)
  127. {
  128. _events.insert(std::make_pair(event, script));
  129. }
  130. private:
  131. std::map<std::string, Script> _events;
  132. };
  133.  
  134. class FastObject
  135. {
  136. public:
  137. int execute(EventType::Type id) const
  138. {
  139. auto it = _events.find(id);
  140. if(it!=_events.end())
  141. {
  142. return it->second.execute();
  143. }
  144. return 0;
  145. }
  146. void addevent(EventType::Type event, const Script &script)
  147. {
  148. _events.insert(std::make_pair(event, script));
  149. }
  150. private:
  151. std::map<EventType::Type, Script> _events;
  152. };
  153.  
  154. using TEventId = const std::string*;
  155. class TEventStorer: public std::unordered_set<std::string> {
  156. public:
  157. TEventId Add(const std::string& event) {
  158. return &(*this->insert(event).first);
  159. }
  160. TEventId Find(const std::string& event) {
  161. auto it = this->find(event);
  162. return it != this->end() ? &(*it) : nullptr;
  163. }
  164. };
  165.  
  166. class SuperFastObject
  167. {
  168. public:
  169. int execute(TEventId event) const
  170. {
  171. auto it = _events.find(event);
  172. if(it!=_events.end())
  173. {
  174. return it->second.execute();
  175. }
  176. return 0;
  177. }
  178. void addevent(TEventId event, Script script)
  179. {
  180. _events.insert(make_pair(event, script));
  181. }
  182. private:
  183. std::map<TEventId, Script> _events;
  184. };
  185.  
  186. std::vector<std::string> eventIds= {
  187. "event00",
  188. "event01",
  189. "event02",
  190. "event03",
  191. "event04",
  192. "event05",
  193. "event06",
  194. "event07",
  195. "event08",
  196. "event09",
  197. "event00",
  198. "event11",
  199. "event12",
  200. "event13",
  201. "event14",
  202. "event15",
  203. "event16",
  204. "event17",
  205. "event18",
  206. "event19",
  207. "event20",
  208. "event21",
  209. "event22",
  210. "event23",
  211. "event24",
  212. "event25"
  213. };
  214.  
  215. int main(int argc, const char * argv[])
  216. {
  217. std::random_device rd;
  218. std::default_random_engine engine(rd());
  219. std::vector<int> ids{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
  220.  
  221. std::vector<Object> objects;
  222. std::vector<FastObject> fast_objects;
  223. std::vector<SuperFastObject> super_fast_objects;
  224. TEventStorer event_storer;
  225.  
  226. const static int max_objects = 1000;
  227. const static int iter_count = 1000;
  228. const static int repeat_count = 1;
  229.  
  230. objects.reserve(max_objects);
  231. fast_objects.reserve(max_objects);
  232. super_fast_objects.reserve(max_objects);
  233.  
  234. for(int i=0;i<max_objects;++i)
  235. {
  236. std::shuffle(ids.begin(), ids.end(), engine);
  237. Object obj1;
  238. FastObject obj2;
  239. SuperFastObject obj3;
  240. for(int j=0;j<10;++j) //add first 10 elements not all object has all events
  241. {
  242. obj1.addevent(eventIds[ids[j]], Script(j));
  243. obj2.addevent(EventType::get(eventIds[ids[j]]), Script(j));
  244. obj3.addevent(event_storer.Add(eventIds[ids[j]]), Script(j));
  245. }
  246. objects.push_back(obj1);
  247. fast_objects.push_back(obj2);
  248. super_fast_objects.push_back(obj3);
  249. }
  250.  
  251. std::vector<std::string> events;
  252. std::vector<EventType::Type> fast_events;
  253. std::vector<TEventId> super_fast_events;
  254.  
  255. events.reserve(eventIds.size()*iter_count);
  256.  
  257. for(int i=0;i<iter_count;++i)
  258. for(const auto &it:eventIds)
  259. {
  260. events.push_back(it);
  261. fast_events.push_back(EventType::find(it));
  262. super_fast_events.push_back(event_storer.Find(it));
  263. }
  264.  
  265.  
  266. int ret1 = 0;
  267. int ret2 = 0;
  268. int ret3 = 0;
  269.  
  270. {
  271. std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
  272. for(int i=0;i<repeat_count;++i)
  273. for(const auto &event:events)
  274. {
  275. for(const auto &object:objects)
  276. {
  277. ret1 += object.execute(event);
  278. }
  279. }
  280. auto duration = std::chrono::high_resolution_clock::now() - t;
  281. std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << ":" << ret1 << std::endl;
  282. }
  283.  
  284. {
  285. std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
  286. for(int i=0;i<repeat_count;++i)
  287. for(const auto &event:fast_events)
  288. {
  289. if(event) //possible that no one has this id
  290. for(const auto &object:fast_objects)
  291. {
  292. ret2 += object.execute(event);
  293. }
  294. }
  295. auto duration = std::chrono::high_resolution_clock::now() - t;
  296. std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << ":" << ret2 << std::endl;
  297. }
  298.  
  299. {
  300. std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
  301. for(int i=0;i<repeat_count;++i)
  302. for(auto&& event:super_fast_events)
  303. {
  304. if(event) //possible that no one has this id
  305. for(auto&& object:super_fast_objects)
  306. {
  307. ret3 += object.execute(event);
  308. }
  309. }
  310. auto duration = std::chrono::high_resolution_clock::now() - t;
  311. std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << ":" << ret3 << std::endl;
  312. }
  313.  
  314. return 0;
  315. }
  316.  
Success #stdin #stdout 4.57s 3568KB
stdin
Standard input is empty
stdout
2788:46375000
868:46375000
929:46375000