fzy

terminal fuzzy finder picker

git clone https://9o.is/git/fzy.git

commit c38e32f36780a5bc45b879e8db3f84778e3de8ab
parent 99f9e472e77de68533fa1c150bcab6bc86235582
Author: John Hawthorn <john.hawthorn@gmail.com>
Date:   Thu, 21 Apr 2016 11:12:15 -0700

Read entire input into contiguous memory

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.

Diffstat:
Mfzy.c | 39+++++++++++++++++++++++++++------------
1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/fzy.c b/fzy.c @@ -19,19 +19,34 @@ static size_t scrolloff = 1; static const char *prompt = "> "; static void read_choices(choices_t *c) { - const char *line; - char buf[4096]; - while (fgets(buf, sizeof buf, stdin)) { - char *nl; - if ((nl = strchr(buf, '\n'))) - *nl = '\0'; - - if (!(line = strdup(buf))) { - fprintf(stderr, "Cannot allocate memory"); - abort(); - } - choices_add(c, line); + size_t bufsize = 65536; + size_t pos = 0; + size_t sizeread; + + /* Read entire file into contiguous memory buffer */ + char *buf = malloc(bufsize); + while ((sizeread = fread(buf + pos, 1, bufsize - pos, stdin))) { + pos += sizeread; + bufsize *= 2; + buf = realloc(buf, bufsize); } + buf = realloc(buf, pos + 1); + + buf[pos] = 0; + + /* Tokenize input and add to choices */ + char *line = buf; + do { + char *nl = strchr(line, '\n'); + if (nl) + *nl++ = '\0'; + + /* Skip empty lines */ + if (*line) + choices_add(c, line); + + line = nl; + } while (line); } #define SEARCH_SIZE_MAX 4096