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