benchmark-line-parsing.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /* SPDX-License-Identifier: GPL-3.0-or-later */
  2. #include <stdio.h>
  3. #include <inttypes.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <sys/time.h>
  8. #define likely(x) __builtin_expect(!!(x), 1)
  9. #define unlikely(x) __builtin_expect(!!(x), 0)
  10. #define simple_hash(name) ({ \
  11. register unsigned char *__hash_source = (unsigned char *)(name); \
  12. register uint32_t __hash_value = 0x811c9dc5; \
  13. while (*__hash_source) { \
  14. __hash_value *= 16777619; \
  15. __hash_value ^= (uint32_t) *__hash_source++; \
  16. } \
  17. __hash_value; \
  18. })
  19. static inline uint32_t simple_hash2(const char *name) {
  20. register unsigned char *s = (unsigned char *)name;
  21. register uint32_t hval = 0x811c9dc5;
  22. while (*s) {
  23. hval *= 16777619;
  24. hval ^= (uint32_t) *s++;
  25. }
  26. return hval;
  27. }
  28. static inline unsigned long long fast_strtoull(const char *s) {
  29. register unsigned long long n = 0;
  30. register char c;
  31. for(c = *s; c >= '0' && c <= '9' ; c = *(++s)) {
  32. n *= 10;
  33. n += c - '0';
  34. // n = (n << 1) + (n << 3) + (c - '0');
  35. }
  36. return n;
  37. }
  38. static uint32_t cache_hash = 0;
  39. static uint32_t rss_hash = 0;
  40. static uint32_t rss_huge_hash = 0;
  41. static uint32_t mapped_file_hash = 0;
  42. static uint32_t writeback_hash = 0;
  43. static uint32_t dirty_hash = 0;
  44. static uint32_t swap_hash = 0;
  45. static uint32_t pgpgin_hash = 0;
  46. static uint32_t pgpgout_hash = 0;
  47. static uint32_t pgfault_hash = 0;
  48. static uint32_t pgmajfault_hash = 0;
  49. static uint32_t inactive_anon_hash = 0;
  50. static uint32_t active_anon_hash = 0;
  51. static uint32_t inactive_file_hash = 0;
  52. static uint32_t active_file_hash = 0;
  53. static uint32_t unevictable_hash = 0;
  54. static uint32_t hierarchical_memory_limit_hash = 0;
  55. static uint32_t total_cache_hash = 0;
  56. static uint32_t total_rss_hash = 0;
  57. static uint32_t total_rss_huge_hash = 0;
  58. static uint32_t total_mapped_file_hash = 0;
  59. static uint32_t total_writeback_hash = 0;
  60. static uint32_t total_dirty_hash = 0;
  61. static uint32_t total_swap_hash = 0;
  62. static uint32_t total_pgpgin_hash = 0;
  63. static uint32_t total_pgpgout_hash = 0;
  64. static uint32_t total_pgfault_hash = 0;
  65. static uint32_t total_pgmajfault_hash = 0;
  66. static uint32_t total_inactive_anon_hash = 0;
  67. static uint32_t total_active_anon_hash = 0;
  68. static uint32_t total_inactive_file_hash = 0;
  69. static uint32_t total_active_file_hash = 0;
  70. static uint32_t total_unevictable_hash = 0;
  71. char *strings[] = {
  72. "cache",
  73. "rss",
  74. "rss_huge",
  75. "mapped_file",
  76. "writeback",
  77. "dirty",
  78. "swap",
  79. "pgpgin",
  80. "pgpgout",
  81. "pgfault",
  82. "pgmajfault",
  83. "inactive_anon",
  84. "active_anon",
  85. "inactive_file",
  86. "active_file",
  87. "unevictable",
  88. "hierarchical_memory_limit",
  89. "total_cache",
  90. "total_rss",
  91. "total_rss_huge",
  92. "total_mapped_file",
  93. "total_writeback",
  94. "total_dirty",
  95. "total_swap",
  96. "total_pgpgin",
  97. "total_pgpgout",
  98. "total_pgfault",
  99. "total_pgmajfault",
  100. "total_inactive_anon",
  101. "total_active_anon",
  102. "total_inactive_file",
  103. "total_active_file",
  104. "total_unevictable",
  105. NULL
  106. };
  107. unsigned long long values1[12] = { 0 };
  108. unsigned long long values2[12] = { 0 };
  109. unsigned long long values3[12] = { 0 };
  110. unsigned long long values4[12] = { 0 };
  111. unsigned long long values5[12] = { 0 };
  112. unsigned long long values6[12] = { 0 };
  113. #define NUMBER1 "12345678901234"
  114. #define NUMBER2 "23456789012345"
  115. #define NUMBER3 "34567890123456"
  116. #define NUMBER4 "45678901234567"
  117. #define NUMBER5 "56789012345678"
  118. #define NUMBER6 "67890123456789"
  119. #define NUMBER7 "78901234567890"
  120. #define NUMBER8 "89012345678901"
  121. #define NUMBER9 "90123456789012"
  122. #define NUMBER10 "12345678901234"
  123. #define NUMBER11 "23456789012345"
  124. // simple system strcmp()
  125. void test1() {
  126. int i;
  127. for(i = 0; strings[i] ; i++) {
  128. char *s = strings[i];
  129. if(unlikely(!strcmp(s, "cache")))
  130. values1[i] = strtoull(NUMBER1, NULL, 10);
  131. else if(unlikely(!strcmp(s, "rss")))
  132. values1[i] = strtoull(NUMBER2, NULL, 10);
  133. else if(unlikely(!strcmp(s, "rss_huge")))
  134. values1[i] = strtoull(NUMBER3, NULL, 10);
  135. else if(unlikely(!strcmp(s, "mapped_file")))
  136. values1[i] = strtoull(NUMBER4, NULL, 10);
  137. else if(unlikely(!strcmp(s, "writeback")))
  138. values1[i] = strtoull(NUMBER5, NULL, 10);
  139. else if(unlikely(!strcmp(s, "dirty")))
  140. values1[i] = strtoull(NUMBER6, NULL, 10);
  141. else if(unlikely(!strcmp(s, "swap")))
  142. values1[i] = strtoull(NUMBER7, NULL, 10);
  143. else if(unlikely(!strcmp(s, "pgpgin")))
  144. values1[i] = strtoull(NUMBER8, NULL, 10);
  145. else if(unlikely(!strcmp(s, "pgpgout")))
  146. values1[i] = strtoull(NUMBER9, NULL, 10);
  147. else if(unlikely(!strcmp(s, "pgfault")))
  148. values1[i] = strtoull(NUMBER10, NULL, 10);
  149. else if(unlikely(!strcmp(s, "pgmajfault")))
  150. values1[i] = strtoull(NUMBER11, NULL, 10);
  151. }
  152. }
  153. // inline simple_hash() with system strtoull()
  154. void test2() {
  155. int i;
  156. for(i = 0; strings[i] ; i++) {
  157. char *s = strings[i];
  158. uint32_t hash = simple_hash2(s);
  159. if(unlikely(hash == cache_hash && !strcmp(s, "cache")))
  160. values2[i] = strtoull(NUMBER1, NULL, 10);
  161. else if(unlikely(hash == rss_hash && !strcmp(s, "rss")))
  162. values2[i] = strtoull(NUMBER2, NULL, 10);
  163. else if(unlikely(hash == rss_huge_hash && !strcmp(s, "rss_huge")))
  164. values2[i] = strtoull(NUMBER3, NULL, 10);
  165. else if(unlikely(hash == mapped_file_hash && !strcmp(s, "mapped_file")))
  166. values2[i] = strtoull(NUMBER4, NULL, 10);
  167. else if(unlikely(hash == writeback_hash && !strcmp(s, "writeback")))
  168. values2[i] = strtoull(NUMBER5, NULL, 10);
  169. else if(unlikely(hash == dirty_hash && !strcmp(s, "dirty")))
  170. values2[i] = strtoull(NUMBER6, NULL, 10);
  171. else if(unlikely(hash == swap_hash && !strcmp(s, "swap")))
  172. values2[i] = strtoull(NUMBER7, NULL, 10);
  173. else if(unlikely(hash == pgpgin_hash && !strcmp(s, "pgpgin")))
  174. values2[i] = strtoull(NUMBER8, NULL, 10);
  175. else if(unlikely(hash == pgpgout_hash && !strcmp(s, "pgpgout")))
  176. values2[i] = strtoull(NUMBER9, NULL, 10);
  177. else if(unlikely(hash == pgfault_hash && !strcmp(s, "pgfault")))
  178. values2[i] = strtoull(NUMBER10, NULL, 10);
  179. else if(unlikely(hash == pgmajfault_hash && !strcmp(s, "pgmajfault")))
  180. values2[i] = strtoull(NUMBER11, NULL, 10);
  181. }
  182. }
  183. // statement expression simple_hash(), system strtoull()
  184. void test3() {
  185. int i;
  186. for(i = 0; strings[i] ; i++) {
  187. char *s = strings[i];
  188. uint32_t hash = simple_hash(s);
  189. if(unlikely(hash == cache_hash && !strcmp(s, "cache")))
  190. values3[i] = strtoull(NUMBER1, NULL, 10);
  191. else if(unlikely(hash == rss_hash && !strcmp(s, "rss")))
  192. values3[i] = strtoull(NUMBER2, NULL, 10);
  193. else if(unlikely(hash == rss_huge_hash && !strcmp(s, "rss_huge")))
  194. values3[i] = strtoull(NUMBER3, NULL, 10);
  195. else if(unlikely(hash == mapped_file_hash && !strcmp(s, "mapped_file")))
  196. values3[i] = strtoull(NUMBER4, NULL, 10);
  197. else if(unlikely(hash == writeback_hash && !strcmp(s, "writeback")))
  198. values3[i] = strtoull(NUMBER5, NULL, 10);
  199. else if(unlikely(hash == dirty_hash && !strcmp(s, "dirty")))
  200. values3[i] = strtoull(NUMBER6, NULL, 10);
  201. else if(unlikely(hash == swap_hash && !strcmp(s, "swap")))
  202. values3[i] = strtoull(NUMBER7, NULL, 10);
  203. else if(unlikely(hash == pgpgin_hash && !strcmp(s, "pgpgin")))
  204. values3[i] = strtoull(NUMBER8, NULL, 10);
  205. else if(unlikely(hash == pgpgout_hash && !strcmp(s, "pgpgout")))
  206. values3[i] = strtoull(NUMBER9, NULL, 10);
  207. else if(unlikely(hash == pgfault_hash && !strcmp(s, "pgfault")))
  208. values3[i] = strtoull(NUMBER10, NULL, 10);
  209. else if(unlikely(hash == pgmajfault_hash && !strcmp(s, "pgmajfault")))
  210. values3[i] = strtoull(NUMBER11, NULL, 10);
  211. }
  212. }
  213. // inline simple_hash(), if-continue checks
  214. void test4() {
  215. int i;
  216. for(i = 0; strings[i] ; i++) {
  217. char *s = strings[i];
  218. uint32_t hash = simple_hash2(s);
  219. if(unlikely(hash == cache_hash && !strcmp(s, "cache"))) {
  220. values4[i] = strtoull(NUMBER1, NULL, 0);
  221. continue;
  222. }
  223. if(unlikely(hash == rss_hash && !strcmp(s, "rss"))) {
  224. values4[i] = strtoull(NUMBER2, NULL, 0);
  225. continue;
  226. }
  227. if(unlikely(hash == rss_huge_hash && !strcmp(s, "rss_huge"))) {
  228. values4[i] = strtoull(NUMBER3, NULL, 0);
  229. continue;
  230. }
  231. if(unlikely(hash == mapped_file_hash && !strcmp(s, "mapped_file"))) {
  232. values4[i] = strtoull(NUMBER4, NULL, 0);
  233. continue;
  234. }
  235. if(unlikely(hash == writeback_hash && !strcmp(s, "writeback"))) {
  236. values4[i] = strtoull(NUMBER5, NULL, 0);
  237. continue;
  238. }
  239. if(unlikely(hash == dirty_hash && !strcmp(s, "dirty"))) {
  240. values4[i] = strtoull(NUMBER6, NULL, 0);
  241. continue;
  242. }
  243. if(unlikely(hash == swap_hash && !strcmp(s, "swap"))) {
  244. values4[i] = strtoull(NUMBER7, NULL, 0);
  245. continue;
  246. }
  247. if(unlikely(hash == pgpgin_hash && !strcmp(s, "pgpgin"))) {
  248. values4[i] = strtoull(NUMBER8, NULL, 0);
  249. continue;
  250. }
  251. if(unlikely(hash == pgpgout_hash && !strcmp(s, "pgpgout"))) {
  252. values4[i] = strtoull(NUMBER9, NULL, 0);
  253. continue;
  254. }
  255. if(unlikely(hash == pgfault_hash && !strcmp(s, "pgfault"))) {
  256. values4[i] = strtoull(NUMBER10, NULL, 0);
  257. continue;
  258. }
  259. if(unlikely(hash == pgmajfault_hash && !strcmp(s, "pgmajfault"))) {
  260. values4[i] = strtoull(NUMBER11, NULL, 0);
  261. continue;
  262. }
  263. }
  264. }
  265. // inline simple_hash(), if-else-if-else-if (netdata default)
  266. void test5() {
  267. int i;
  268. for(i = 0; strings[i] ; i++) {
  269. char *s = strings[i];
  270. uint32_t hash = simple_hash2(s);
  271. if(unlikely(hash == cache_hash && !strcmp(s, "cache")))
  272. values5[i] = fast_strtoull(NUMBER1);
  273. else if(unlikely(hash == rss_hash && !strcmp(s, "rss")))
  274. values5[i] = fast_strtoull(NUMBER2);
  275. else if(unlikely(hash == rss_huge_hash && !strcmp(s, "rss_huge")))
  276. values5[i] = fast_strtoull(NUMBER3);
  277. else if(unlikely(hash == mapped_file_hash && !strcmp(s, "mapped_file")))
  278. values5[i] = fast_strtoull(NUMBER4);
  279. else if(unlikely(hash == writeback_hash && !strcmp(s, "writeback")))
  280. values5[i] = fast_strtoull(NUMBER5);
  281. else if(unlikely(hash == dirty_hash && !strcmp(s, "dirty")))
  282. values5[i] = fast_strtoull(NUMBER6);
  283. else if(unlikely(hash == swap_hash && !strcmp(s, "swap")))
  284. values5[i] = fast_strtoull(NUMBER7);
  285. else if(unlikely(hash == pgpgin_hash && !strcmp(s, "pgpgin")))
  286. values5[i] = fast_strtoull(NUMBER8);
  287. else if(unlikely(hash == pgpgout_hash && !strcmp(s, "pgpgout")))
  288. values5[i] = fast_strtoull(NUMBER9);
  289. else if(unlikely(hash == pgfault_hash && !strcmp(s, "pgfault")))
  290. values5[i] = fast_strtoull(NUMBER10);
  291. else if(unlikely(hash == pgmajfault_hash && !strcmp(s, "pgmajfault")))
  292. values5[i] = fast_strtoull(NUMBER11);
  293. }
  294. }
  295. // ----------------------------------------------------------------------------
  296. struct entry {
  297. char *name;
  298. uint32_t hash;
  299. int found;
  300. void (*func)(void *data1, void *data2);
  301. void *data1;
  302. void *data2;
  303. struct entry *prev, *next;
  304. };
  305. struct base {
  306. int iteration;
  307. int registered;
  308. int wanted;
  309. int found;
  310. struct entry *entries, *last;
  311. };
  312. static inline void callback(void *data1, void *data2) {
  313. char *string = data1;
  314. unsigned long long *value = data2;
  315. *value = fast_strtoull(string);
  316. }
  317. static inline void callback_system_strtoull(void *data1, void *data2) {
  318. char *string = data1;
  319. unsigned long long *value = data2;
  320. *value = strtoull(string, NULL, 10);
  321. }
  322. static inline struct base *entry(struct base *base, const char *name, void *data1, void *data2, void (*func)(void *, void *)) {
  323. if(!base)
  324. base = calloc(1, sizeof(struct base));
  325. struct entry *e = malloc(sizeof(struct entry));
  326. e->name = strdup(name);
  327. e->hash = simple_hash2(e->name);
  328. e->data1 = data1;
  329. e->data2 = data2;
  330. e->func = func;
  331. e->prev = NULL;
  332. e->next = base->entries;
  333. if(base->entries) base->entries->prev = e;
  334. else base->last = e;
  335. base->entries = e;
  336. base->registered++;
  337. base->wanted = base->registered;
  338. return base;
  339. }
  340. static inline int check(struct base *base, const char *s) {
  341. uint32_t hash = simple_hash2(s);
  342. if(likely(!strcmp(s, base->last->name))) {
  343. base->last->found = 1;
  344. base->found++;
  345. if(base->last->func) base->last->func(base->last->data1, base->last->data2);
  346. base->last = base->last->next;
  347. if(!base->last)
  348. base->last = base->entries;
  349. if(base->found == base->registered)
  350. return 1;
  351. return 0;
  352. }
  353. // find it
  354. struct entry *e;
  355. for(e = base->entries; e ; e = e->next)
  356. if(e->hash == hash && !strcmp(e->name, s))
  357. break;
  358. if(e == base->last) {
  359. printf("ERROR\n");
  360. exit(1);
  361. }
  362. if(e) {
  363. // found
  364. // run it
  365. if(e->func) e->func(e->data1, e->data2);
  366. // unlink it
  367. if(e->next) e->next->prev = e->prev;
  368. if(e->prev) e->prev->next = e->next;
  369. if(base->entries == e)
  370. base->entries = e->next;
  371. }
  372. else {
  373. // not found
  374. // create it
  375. e = calloc(1, sizeof(struct entry));
  376. e->name = strdup(s);
  377. e->hash = hash;
  378. }
  379. // link it here
  380. e->next = base->last;
  381. if(base->last) {
  382. e->prev = base->last->prev;
  383. base->last->prev = e;
  384. if(base->entries == base->last)
  385. base->entries = e;
  386. }
  387. else
  388. e->prev = NULL;
  389. if(e->prev)
  390. e->prev->next = e;
  391. base->last = e->next;
  392. if(!base->last)
  393. base->last = base->entries;
  394. e->found = 1;
  395. base->found++;
  396. if(base->found == base->registered)
  397. return 1;
  398. printf("relinked '%s' after '%s' and before '%s': ", e->name, e->prev?e->prev->name:"NONE", e->next?e->next->name:"NONE");
  399. for(e = base->entries; e ; e = e->next) printf("%s ", e->name);
  400. printf("\n");
  401. return 0;
  402. }
  403. static inline void begin(struct base *base) {
  404. if(unlikely(base->iteration % 60) == 1) {
  405. base->wanted = 0;
  406. struct entry *e;
  407. for(e = base->entries; e ; e = e->next)
  408. if(e->found) base->wanted++;
  409. }
  410. base->iteration++;
  411. base->last = base->entries;
  412. base->found = 0;
  413. }
  414. void test6() {
  415. static struct base *base = NULL;
  416. if(unlikely(!base)) {
  417. base = entry(base, "cache", NUMBER1, &values6[0], callback_system_strtoull);
  418. base = entry(base, "rss", NUMBER2, &values6[1], callback_system_strtoull);
  419. base = entry(base, "rss_huge", NUMBER3, &values6[2], callback_system_strtoull);
  420. base = entry(base, "mapped_file", NUMBER4, &values6[3], callback_system_strtoull);
  421. base = entry(base, "writeback", NUMBER5, &values6[4], callback_system_strtoull);
  422. base = entry(base, "dirty", NUMBER6, &values6[5], callback_system_strtoull);
  423. base = entry(base, "swap", NUMBER7, &values6[6], callback_system_strtoull);
  424. base = entry(base, "pgpgin", NUMBER8, &values6[7], callback_system_strtoull);
  425. base = entry(base, "pgpgout", NUMBER9, &values6[8], callback_system_strtoull);
  426. base = entry(base, "pgfault", NUMBER10, &values6[9], callback_system_strtoull);
  427. base = entry(base, "pgmajfault", NUMBER11, &values6[10], callback_system_strtoull);
  428. }
  429. begin(base);
  430. int i;
  431. for(i = 0; strings[i] ; i++) {
  432. if(check(base, strings[i]))
  433. break;
  434. }
  435. }
  436. void test7() {
  437. static struct base *base = NULL;
  438. if(unlikely(!base)) {
  439. base = entry(base, "cache", NUMBER1, &values6[0], callback);
  440. base = entry(base, "rss", NUMBER2, &values6[1], callback);
  441. base = entry(base, "rss_huge", NUMBER3, &values6[2], callback);
  442. base = entry(base, "mapped_file", NUMBER4, &values6[3], callback);
  443. base = entry(base, "writeback", NUMBER5, &values6[4], callback);
  444. base = entry(base, "dirty", NUMBER6, &values6[5], callback);
  445. base = entry(base, "swap", NUMBER7, &values6[6], callback);
  446. base = entry(base, "pgpgin", NUMBER8, &values6[7], callback);
  447. base = entry(base, "pgpgout", NUMBER9, &values6[8], callback);
  448. base = entry(base, "pgfault", NUMBER10, &values6[9], callback);
  449. base = entry(base, "pgmajfault", NUMBER11, &values6[10], callback);
  450. }
  451. begin(base);
  452. int i;
  453. for(i = 0; strings[i] ; i++) {
  454. if(check(base, strings[i]))
  455. break;
  456. }
  457. }
  458. // ----------------------------------------------------------------------------
  459. // ==============
  460. // --- Poor man cycle counting.
  461. static unsigned long tsc;
  462. static void begin_tsc(void)
  463. {
  464. unsigned long a, d;
  465. asm volatile ("cpuid\nrdtsc" : "=a" (a), "=d" (d) : "0" (0) : "ebx", "ecx");
  466. tsc = ((unsigned long)d << 32) | (unsigned long)a;
  467. }
  468. static unsigned long end_tsc(void)
  469. {
  470. unsigned long a, d;
  471. asm volatile ("rdtscp" : "=a" (a), "=d" (d) : : "ecx");
  472. return (((unsigned long)d << 32) | (unsigned long)a) - tsc;
  473. }
  474. // ===============
  475. static unsigned long long clk;
  476. static void begin_clock() {
  477. struct timeval tv;
  478. if(unlikely(gettimeofday(&tv, NULL) == -1))
  479. return;
  480. clk = tv.tv_sec * 1000000 + tv.tv_usec;
  481. }
  482. static unsigned long long end_clock() {
  483. struct timeval tv;
  484. if(unlikely(gettimeofday(&tv, NULL) == -1))
  485. return -1;
  486. return clk = tv.tv_sec * 1000000 + tv.tv_usec - clk;
  487. }
  488. void main(void)
  489. {
  490. cache_hash = simple_hash("cache");
  491. rss_hash = simple_hash("rss");
  492. rss_huge_hash = simple_hash("rss_huge");
  493. mapped_file_hash = simple_hash("mapped_file");
  494. writeback_hash = simple_hash("writeback");
  495. dirty_hash = simple_hash("dirty");
  496. swap_hash = simple_hash("swap");
  497. pgpgin_hash = simple_hash("pgpgin");
  498. pgpgout_hash = simple_hash("pgpgout");
  499. pgfault_hash = simple_hash("pgfault");
  500. pgmajfault_hash = simple_hash("pgmajfault");
  501. inactive_anon_hash = simple_hash("inactive_anon");
  502. active_anon_hash = simple_hash("active_anon");
  503. inactive_file_hash = simple_hash("inactive_file");
  504. active_file_hash = simple_hash("active_file");
  505. unevictable_hash = simple_hash("unevictable");
  506. hierarchical_memory_limit_hash = simple_hash("hierarchical_memory_limit");
  507. total_cache_hash = simple_hash("total_cache");
  508. total_rss_hash = simple_hash("total_rss");
  509. total_rss_huge_hash = simple_hash("total_rss_huge");
  510. total_mapped_file_hash = simple_hash("total_mapped_file");
  511. total_writeback_hash = simple_hash("total_writeback");
  512. total_dirty_hash = simple_hash("total_dirty");
  513. total_swap_hash = simple_hash("total_swap");
  514. total_pgpgin_hash = simple_hash("total_pgpgin");
  515. total_pgpgout_hash = simple_hash("total_pgpgout");
  516. total_pgfault_hash = simple_hash("total_pgfault");
  517. total_pgmajfault_hash = simple_hash("total_pgmajfault");
  518. total_inactive_anon_hash = simple_hash("total_inactive_anon");
  519. total_active_anon_hash = simple_hash("total_active_anon");
  520. total_inactive_file_hash = simple_hash("total_inactive_file");
  521. total_active_file_hash = simple_hash("total_active_file");
  522. total_unevictable_hash = simple_hash("total_unevictable");
  523. unsigned long i, c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7;
  524. unsigned long max = 1000000;
  525. // let the processor get up to speed
  526. begin_clock();
  527. for(i = 0; i <= max ;i++) test1();
  528. c1 = end_clock();
  529. begin_clock();
  530. for(i = 0; i <= max ;i++) test1();
  531. c1 = end_clock();
  532. begin_clock();
  533. for(i = 0; i <= max ;i++) test2();
  534. c2 = end_clock();
  535. begin_clock();
  536. for(i = 0; i <= max ;i++) test3();
  537. c3 = end_clock();
  538. begin_clock();
  539. for(i = 0; i <= max ;i++) test4();
  540. c4 = end_clock();
  541. begin_clock();
  542. for(i = 0; i <= max ;i++) test5();
  543. c5 = end_clock();
  544. begin_clock();
  545. for(i = 0; i <= max ;i++) test6();
  546. c6 = end_clock();
  547. begin_clock();
  548. for(i = 0; i <= max ;i++) test7();
  549. c7 = end_clock();
  550. for(i = 0; i < 11 ; i++)
  551. printf("value %lu: %llu %llu %llu %llu %llu %llu\n", i, values1[i], values2[i], values3[i], values4[i], values5[i], values6[i]);
  552. printf("\n\nRESULTS\n");
  553. printf("test1() in %lu usecs: if-else-if-else-if, simple strcmp() with system strtoull().\n"
  554. "test2() in %lu usecs: inline simple_hash() if-else-if-else-if, with system strtoull().\n"
  555. "test3() in %lu usecs: statement expression simple_hash(), system strtoull().\n"
  556. "test4() in %lu usecs: inline simple_hash(), if-continue checks, system strtoull().\n"
  557. "test5() in %lu usecs: inline simple_hash(), if-else-if-else-if, custom strtoull() (netdata default prior to ARL).\n"
  558. "test6() in %lu usecs: adaptive re-sortable list, system strtoull() (wow!)\n"
  559. "test7() in %lu usecs: adaptive re-sortable list, custom strtoull() (wow!)\n"
  560. , c1
  561. , c2
  562. , c3
  563. , c4
  564. , c5
  565. , c6
  566. , c7
  567. );
  568. }