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