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:
| M | fzy.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