This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <assert.h> | |
| #include <time.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #if 1 | |
| #include "khash.h" | |
| // causes output: $ gcc -O3 khash-example.c && time ./a.out 32000000 | |
| // causes output: --- generating data... 32000000 * 9 = 288000000 bytes done! | |
| // causes output: [ht_khash_str_put] size: 32000000 | |
| // causes output: [ht_timing] 46.030 sec or 695198.8 per second | |
| // causes output: [ht_khash_str_get] size: 32000000 | |
| // causes output: [ht_timing] 14.180 sec or 2256699.6 per second | |
| #else | |
| #include "khash.h.old" | |
| // causes output: $ gcc -O3 khash-example.c && time ./a.out 32000000 | |
| // causes output: --- generating data... 32000000 * 9 = 288000000 bytes done! | |
| // causes output: [ht_khash_str_put] size: 32000000 | |
| // causes output: [ht_timing] 10.710 sec or 2987861.8 per second | |
| // causes output: [ht_khash_str_get] size: 32000000 | |
| // causes output: [ht_timing] 13.590 sec or 2354672.6 per second | |
| #endif | |
| KHASH_MAP_INIT_STR(str,int) | |
| struct HEXSTR { | |
| char hex[8 + 1]; | |
| } __attribute__((packed)); | |
| static int data_size = 75000000; | |
| static struct HEXSTR * hexstr; | |
| void ht_init_data() | |
| { | |
| int i; | |
| char hexkey[] = "FFFFFFFF"; | |
| printf("--- generating data... "); | |
| hexstr = (struct HEXSTR * )calloc(data_size, sizeof(*hexstr)); | |
| printf("%u * %lu = %lu bytes ", data_size, sizeof(*hexstr), data_size * sizeof(*hexstr)); | |
| for (i = 0; i < data_size; ++i) { | |
| int p = 8 - 1; | |
| while (1) { if ('0' == hexkey[p]) { hexkey[p] = 'F'; p --; } else { if ('A' == hexkey[p]) { hexkey[p] = '9'; break; } else { hexkey[p] --; break; } } } | |
| strcpy(&hexstr[i].hex[0], &hexkey[0]); | |
| } | |
| printf("done!\n"); | |
| } | |
| khash_t(str) *h; | |
| void ht_khash_str_put() | |
| { | |
| int i, ret; | |
| unsigned k; | |
| for (i = 0; i < data_size; ++i) { | |
| k = kh_put(str, h, &hexstr[i].hex[0], &ret); | |
| //if (!ret) kh_del(str, h, k); | |
| if (1 != ret) { | |
| printf("ERROR: unexpected non-empty bucket (i=%d, ret=%d, key=%s)\n", i, ret, &hexstr[i].hex[0]); | |
| exit(1); | |
| } | |
| kh_value(h, k) = i; | |
| } | |
| printf("[ht_khash_str_put] size: %u\n", kh_size(h)); | |
| } | |
| void ht_khash_str_get() | |
| { | |
| int i; | |
| unsigned k; | |
| int j = 0; | |
| for (i = 0; i < data_size; ++i) { | |
| j += 65; | |
| j = j % data_size; | |
| k = kh_get(str, h, &hexstr[j].hex[0]); | |
| int is_missing = (k == kh_end(h)); | |
| if (is_missing) { | |
| printf("ERROR: unexpected missing key (i=%d, key=%s)\n", j, &hexstr[j].hex[0]); | |
| exit(1); | |
| } | |
| else if (j != kh_value(h, k)) { | |
| printf("ERROR: unexpected value (i=%d, key=%s)\n", j, &hexstr[j].hex[0]); | |
| exit(1); | |
| } | |
| } | |
| printf("[ht_khash_str_get] size: %u\n", kh_size(h)); | |
| } | |
| void ht_timing(void (*f)(void)) | |
| { | |
| clock_t t = clock(); | |
| (*f)(); | |
| printf("[ht_timing] %.3lf sec or %.1f per second\n", (double)(clock() - t) / CLOCKS_PER_SEC, data_size / ((double)(clock() - t) / CLOCKS_PER_SEC)); | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| if (argc > 1) data_size = atoi(argv[1]); | |
| ht_init_data(); | |
| h = kh_init(str); | |
| ht_timing(ht_khash_str_put); | |
| ht_timing(ht_khash_str_get); | |
| kh_destroy(str, h); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment