This should be slightly faster at loading the input into memory, since
fewer mallocs will be required vs running one malloc per-line of input.
Realloc on modern systems is fast. It can use mremap internally to remap
virtual memory pages and avoid copying. This can be seen in strace. Neat!
I thought that this might be friendlier to caching, but there was no
noticeable differnce when scanning through the strings for matches. It's
probable that the previous strdups placed them more-or-less contiguously
and the extra padding for malloc bookkeeping didn't make a significant
differnce. This also suggests that alignment of the candidate strings
wasn't important.
| ... | ... |
@@ -19,19 +19,34 @@ static size_t scrolloff = 1; |
| 19 | 19 |
static const char *prompt = "> "; |
| 20 | 20 |
|
| 21 | 21 |
static void read_choices(choices_t *c) {
|
| 22 |
- const char *line; |
|
| 23 |
- char buf[4096]; |
|
| 24 |
- while (fgets(buf, sizeof buf, stdin)) {
|
|
| 25 |
- char *nl; |
|
| 26 |
- if ((nl = strchr(buf, '\n'))) |
|
| 27 |
- *nl = '\0'; |
|
| 28 |
- |
|
| 29 |
- if (!(line = strdup(buf))) {
|
|
| 30 |
- fprintf(stderr, "Cannot allocate memory"); |
|
| 31 |
- abort(); |
|
| 32 |
- } |
|
| 33 |
- choices_add(c, line); |
|
| 22 |
+ size_t bufsize = 65536; |
|
| 23 |
+ size_t pos = 0; |
|
| 24 |
+ size_t sizeread; |
|
| 25 |
+ |
|
| 26 |
+ /* Read entire file into contiguous memory buffer */ |
|
| 27 |
+ char *buf = malloc(bufsize); |
|
| 28 |
+ while ((sizeread = fread(buf + pos, 1, bufsize - pos, stdin))) {
|
|
| 29 |
+ pos += sizeread; |
|
| 30 |
+ bufsize *= 2; |
|
| 31 |
+ buf = realloc(buf, bufsize); |
|
| 34 | 32 |
} |
| 33 |
+ buf = realloc(buf, pos + 1); |
|
| 34 |
+ |
|
| 35 |
+ buf[pos] = 0; |
|
| 36 |
+ |
|
| 37 |
+ /* Tokenize input and add to choices */ |
|
| 38 |
+ char *line = buf; |
|
| 39 |
+ do {
|
|
| 40 |
+ char *nl = strchr(line, '\n'); |
|
| 41 |
+ if (nl) |
|
| 42 |
+ *nl++ = '\0'; |
|
| 43 |
+ |
|
| 44 |
+ /* Skip empty lines */ |
|
| 45 |
+ if (*line) |
|
| 46 |
+ choices_add(c, line); |
|
| 47 |
+ |
|
| 48 |
+ line = nl; |
|
| 49 |
+ } while (line); |
|
| 35 | 50 |
} |
| 36 | 51 |
|
| 37 | 52 |
#define SEARCH_SIZE_MAX 4096 |