fork download
  1. #include <cstring>
  2. #include <chrono>
  3. #include <map>
  4. #include <string>
  5. #include <vector>
  6. #include <unordered_map>
  7. #include <iostream>
  8.  
  9. enum class animal
  10. {
  11. Unknown,
  12. Aardvark,
  13. Albatross,
  14. Alligator,
  15. Alpaca,
  16. AmericanBison,
  17. Ant,
  18. Anteater,
  19. Antelope,
  20. Ape,
  21. Armadillo,
  22. };
  23.  
  24. animal to_animal_naive(const char* s)
  25. {
  26. if (std::strcmp(s, "Aardvark") == 0)
  27. return animal::Aardvark;
  28. if (std::strcmp(s, "Albatross") == 0)
  29. return animal::Albatross;
  30. if (std::strcmp(s, "Alligator") == 0)
  31. return animal::Alligator;
  32. if (std::strcmp(s, "Alpaca") == 0)
  33. return animal::Alpaca;
  34. if (std::strcmp(s, "AmericanBison") == 0)
  35. return animal::AmericanBison;
  36. if (std::strcmp(s, "Ant") == 0)
  37. return animal::Ant;
  38. if (std::strcmp(s, "Anteater") == 0)
  39. return animal::Anteater;
  40. if (std::strcmp(s, "Antelope") == 0)
  41. return animal::Antelope;
  42. if (std::strcmp(s, "Ape") == 0)
  43. return animal::Ape;
  44. if (std::strcmp(s, "Armadillo") == 0)
  45. return animal::Armadillo;
  46. return animal::Unknown;
  47. }
  48.  
  49. animal to_animal_naive_map(const char* s)
  50. {
  51. struct animal_selector
  52. {
  53. std::map<std::string, animal> animal_map_;
  54.  
  55. animal_selector()
  56. {
  57. animal_map_["Aardvark"] = animal::Aardvark;
  58. animal_map_["Albatross"] = animal::Albatross;
  59. animal_map_["Alligator"] = animal::Alligator;
  60. animal_map_["Alpaca"] = animal::Alpaca;
  61. animal_map_["AmericanBison"] = animal::AmericanBison;
  62. animal_map_["Ant"] = animal::Ant;
  63. animal_map_["Anteater"] = animal::Anteater;
  64. animal_map_["Antelope"] = animal::Antelope;
  65. animal_map_["Ape"] = animal::Ape;
  66. animal_map_["Armadillo"] = animal::Armadillo;
  67. }
  68.  
  69. animal operator () (const char* s) const
  70. {
  71. auto found = animal_map_.find(s);
  72. if (found != animal_map_.end())
  73. return found->second;
  74. return animal::Unknown;
  75. }
  76. };
  77.  
  78. static animal_selector selector;
  79.  
  80. return selector(s);
  81. }
  82.  
  83. animal to_animal_map(const char* s)
  84. {
  85. struct animal_selector
  86. {
  87. struct compare
  88. {
  89. bool operator () (const char* s, const char* t) const
  90. {
  91. return std::strcmp(s, t) < 0;
  92. }
  93. };
  94.  
  95. std::map<const char*, animal, compare> animal_map_;
  96.  
  97. animal_selector()
  98. {
  99. animal_map_["Aardvark"] = animal::Aardvark;
  100. animal_map_["Albatross"] = animal::Albatross;
  101. animal_map_["Alligator"] = animal::Alligator;
  102. animal_map_["Alpaca"] = animal::Alpaca;
  103. animal_map_["AmericanBison"] = animal::AmericanBison;
  104. animal_map_["Ant"] = animal::Ant;
  105. animal_map_["Anteater"] = animal::Anteater;
  106. animal_map_["Antelope"] = animal::Antelope;
  107. animal_map_["Ape"] = animal::Ape;
  108. animal_map_["Armadillo"] = animal::Armadillo;
  109. }
  110.  
  111. animal operator () (const char* s) const
  112. {
  113. auto found = animal_map_.find(s);
  114. if (found != animal_map_.end())
  115. return found->second;
  116. return animal::Unknown;
  117. }
  118. };
  119.  
  120. static animal_selector selector;
  121.  
  122. return selector(s);
  123. }
  124.  
  125. animal to_animal_unordered_map(const char* s)
  126. {
  127. struct animal_selector
  128. {
  129. std::unordered_map<std::string, animal> animal_map_;
  130.  
  131. animal_selector()
  132. {
  133. animal_map_["Aardvark"] = animal::Aardvark;
  134. animal_map_["Albatross"] = animal::Albatross;
  135. animal_map_["Alligator"] = animal::Alligator;
  136. animal_map_["Alpaca"] = animal::Alpaca;
  137. animal_map_["AmericanBison"] = animal::AmericanBison;
  138. animal_map_["Ant"] = animal::Ant;
  139. animal_map_["Anteater"] = animal::Anteater;
  140. animal_map_["Antelope"] = animal::Antelope;
  141. animal_map_["Ape"] = animal::Ape;
  142. animal_map_["Armadillo"] = animal::Armadillo;
  143. }
  144.  
  145. animal operator () (const char* s) const
  146. {
  147. auto found = animal_map_.find(s);
  148. if (found != animal_map_.end())
  149. return found->second;
  150. return animal::Unknown;
  151. }
  152. };
  153.  
  154. static animal_selector selector;
  155.  
  156. return selector(s);
  157. }
  158.  
  159. template <animal A>
  160. struct this_or_unknown
  161. {
  162. animal operator () (const char* s, const char* t) const
  163. {
  164. return std::strcmp(s, t) == 0 ? A : animal::Unknown;
  165. }
  166. };
  167.  
  168. animal to_animal_switch_only(const char* s)
  169. {
  170. switch (*s++)
  171. {
  172. default:
  173. return animal::Unknown;
  174. case 'A':
  175. switch (*s++)
  176. {
  177. default:
  178. return animal::Unknown;
  179. case 'a':
  180. return this_or_unknown<animal::Aardvark>()(s, "rdvark");
  181. case 'l':
  182. switch (*s++)
  183. {
  184. default:
  185. return animal::Unknown;
  186. case 'b':
  187. return this_or_unknown<animal::Albatross>()(s, "atross");
  188. case 'l':
  189. return this_or_unknown<animal::Alligator>()(s, "igator");
  190. case 'p':
  191. return this_or_unknown<animal::Alpaca>()(s, "aca");
  192. }
  193. case 'm':
  194. return this_or_unknown<animal::AmericanBison>()(s, "ericanBison");
  195. case 'n':
  196. switch (*s++)
  197. {
  198. default:
  199. return animal::Unknown;
  200. case 't':
  201. switch (*s++)
  202. {
  203. default:
  204. return animal::Unknown;
  205. case '\0':
  206. return animal::Ant;
  207. case 'e':
  208. switch (*s++)
  209. {
  210. default:
  211. return animal::Unknown;
  212. case 'a':
  213. return this_or_unknown<animal::Anteater>()(s, "ter");
  214. case 'l':
  215. return this_or_unknown<animal::Antelope>()(s, "ope");
  216. }
  217. }
  218. }
  219. case 'p':
  220. return *s == 'e' ? animal::Ape : animal::Unknown;
  221. case 'r':
  222. return this_or_unknown<animal::Armadillo>()(s, "madillo");
  223. }
  224. }
  225. }
  226.  
  227. animal to_animal_if_only(const char* s)
  228. {
  229. if (*s++ == 'A')
  230. {
  231. if (*s == 'a')
  232. {
  233. return this_or_unknown<animal::Aardvark>()(++s, "rdvark");
  234. }
  235. else if (*s == 'l')
  236. {
  237. ++s;
  238. if (*s == 'b')
  239. return this_or_unknown<animal::Albatross>()(++s, "atross");
  240. else if (*s == 'l')
  241. return this_or_unknown<animal::Alligator>()(++s, "igator");
  242. else if (*s == 'p')
  243. return this_or_unknown<animal::Alpaca>()(++s, "aca");
  244. }
  245. else if (*s == 'm')
  246. {
  247. return this_or_unknown<animal::AmericanBison>()(++s, "ericanBison");
  248. }
  249. else if (*s == 'n')
  250. {
  251. ++s;
  252. if (*s++ == 't')
  253. {
  254. if (*s == '\0')
  255. {
  256. return animal::Ant;
  257. }
  258. else if (*s++ == 'e')
  259. {
  260. if (*s == 'a')
  261. return this_or_unknown<animal::Anteater>()(++s, "ter");
  262. else if (*s == 'l')
  263. return this_or_unknown<animal::Antelope>()(++s, "ope");
  264. }
  265. }
  266. }
  267. else if (*s == 'p' && *++s == 'e')
  268. {
  269. return animal::Ape;
  270. }
  271. else if (*s == 'r')
  272. {
  273. return this_or_unknown<animal::Armadillo>()(s, "madillo");
  274. }
  275. }
  276. return animal::Unknown;
  277. }
  278.  
  279. animal to_animal_nice_mix(const char* s)
  280. {
  281. if (*s++ == 'A')
  282. {
  283. switch (*s++)
  284. {
  285. default:
  286. break;
  287. case 'a':
  288. return this_or_unknown<animal::Aardvark>()(s, "rdvark");
  289. case 'l':
  290. if (*s == 'b')
  291. return this_or_unknown<animal::Albatross>()(++s, "atross");
  292. else if (*s == 'l')
  293. return this_or_unknown<animal::Alligator>()(++s, "igator");
  294. else if (*s == 'p')
  295. return this_or_unknown<animal::Alpaca>()(++s, "aca");
  296. break;
  297. case 'm':
  298. return this_or_unknown<animal::AmericanBison>()(s, "ericanBison");
  299. case 'n':
  300. if (*s++ == 't')
  301. {
  302. if (*s == '\0')
  303. {
  304. return animal::Ant;
  305. }
  306. else if (*s++ == 'e')
  307. {
  308. if (*s == 'a')
  309. return this_or_unknown<animal::Anteater>()(++s, "ter");
  310. else if (*s == 'l')
  311. return this_or_unknown<animal::Antelope>()(++s, "ope");
  312. }
  313. }
  314. break;
  315. case 'p':
  316. return *s == 'e' ? animal::Ape : animal::Unknown;
  317. case 'r':
  318. return this_or_unknown<animal::Armadillo>()(s, "madillo");
  319. }
  320. }
  321. return animal::Unknown;
  322. }
  323.  
  324. template <typename Clock = std::chrono::high_resolution_clock>
  325. class stopwatch
  326. {
  327. typename Clock::time_point last_;
  328.  
  329. public:
  330. stopwatch()
  331. : last_(Clock::now())
  332. {}
  333.  
  334. void reset()
  335. {
  336. *this = stopwatch();
  337. }
  338.  
  339. typename Clock::duration elapsed() const
  340. {
  341. return Clock::now() - last_;
  342. }
  343.  
  344. typename Clock::duration tick()
  345. {
  346. auto now = Clock::now();
  347. auto elapsed = now - last_;
  348. last_ = now;
  349. return elapsed;
  350. }
  351. };
  352.  
  353. template <typename T, typename Rep, typename Period>
  354. T duration_cast(const std::chrono::duration<Rep, Period>& duration)
  355. {
  356. return duration.count() * static_cast<T>(Period::num) / static_cast<T>(Period::den);
  357. }
  358.  
  359. int main()
  360. {
  361. //while (true)
  362. //{
  363. std::size_t max_iterations;
  364. std::cout << "Max iterations: ";
  365. std::cin >> max_iterations;
  366.  
  367. std::vector<std::string> animals;
  368. std::cout << "Enter animals:\n";
  369. for (std::string s;;)
  370. {
  371. std::cin >> s;
  372.  
  373. if (s == "start")
  374. break;
  375.  
  376. animals.push_back(s);
  377. }
  378.  
  379. stopwatch<> sw;
  380. double t;
  381.  
  382. sw.reset();
  383. for (auto i = max_iterations; i--; )
  384. {
  385. animal a = to_animal_naive(animals[i % animals.size()].c_str());
  386. if (i % 13373 == 0 && a == animal::Albatross)
  387. std::cout << '.';
  388. }
  389. std::cout << '\n';
  390. t = duration_cast<double>(sw.elapsed());
  391. std::cout << "to_animal_naive: " << t << '\n';
  392.  
  393. sw.reset();
  394. for (auto i = max_iterations; i--; )
  395. {
  396. animal a = to_animal_naive_map(animals[i % animals.size()].c_str());
  397. if (i % 13373 == 0 && a == animal::Albatross)
  398. std::cout << '.';
  399. }
  400. std::cout << '\n';
  401. t = duration_cast<double>(sw.elapsed());
  402. std::cout << "to_animal_naive_map: " << t << '\n';
  403.  
  404. sw.reset();
  405. for (auto i = max_iterations; i--; )
  406. {
  407. animal a = to_animal_map(animals[i % animals.size()].c_str());
  408. if (i % 13373 == 0 && a == animal::Albatross)
  409. std::cout << '.';
  410. }
  411. std::cout << '\n';
  412. t = duration_cast<double>(sw.elapsed());
  413. std::cout << "to_animal_map: " << t << '\n';
  414.  
  415. sw.reset();
  416. for (auto i = max_iterations; i--; )
  417. {
  418. animal a = to_animal_unordered_map(animals[i % animals.size()].c_str());
  419. if (i % 13373 == 0 && a == animal::Albatross)
  420. std::cout << '.';
  421. }
  422. std::cout << '\n';
  423. t = duration_cast<double>(sw.elapsed());
  424. std::cout << "to_animal_unordered_map: " << t << '\n';
  425.  
  426. sw.reset();
  427. for (auto i = max_iterations; i--; )
  428. {
  429. animal a = to_animal_switch_only(animals[i % animals.size()].c_str());
  430. if (i % 13373 == 0 && a == animal::Albatross)
  431. std::cout << '.';
  432. }
  433. std::cout << '\n';
  434. t = duration_cast<double>(sw.elapsed());
  435. std::cout << "to_animal_switch_only: " << t << '\n';
  436.  
  437. sw.reset();
  438. for (auto i = max_iterations; i--; )
  439. {
  440. animal a = to_animal_if_only(animals[i % animals.size()].c_str());
  441. if (i % 13373 == 0 && a == animal::Albatross)
  442. std::cout << '.';
  443. }
  444. std::cout << '\n';
  445. t = duration_cast<double>(sw.elapsed());
  446. std::cout << "to_animal_if_only: " << t << '\n';
  447.  
  448. sw.reset();
  449. for (auto i = max_iterations; i--; )
  450. {
  451. animal a = to_animal_nice_mix(animals[i % animals.size()].c_str());
  452. if (i % 13373 == 0 && a == animal::Albatross)
  453. std::cout << '.';
  454. }
  455. std::cout << '\n';
  456. t = duration_cast<double>(sw.elapsed());
  457. std::cout << "to_animal_nice_mix: " << t << '\n';
  458. //}
  459. }
Success #stdin #stdout 0.78s 3088KB
stdin
1000000
Kleine Namen Aber Affe Ape Algen Allgemein Anteater Armadillo Albatross Alligator AmericanBison Antelope start
stdout
Max iterations: Enter animals:
......
to_animal_naive: 0.111903
......
to_animal_naive_map: 0.247395
......
to_animal_map: 0.090593
......
to_animal_unordered_map: 0.225098
......
to_animal_switch_only: 0.03257
......
to_animal_if_only: 0.031715
......
to_animal_nice_mix: 0.036592